diff options
Diffstat (limited to 'fs')
225 files changed, 4580 insertions, 4222 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7a7ec2d1d2f..5241c600ce2 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -233,7 +233,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) inode->i_op = &v9fs_symlink_inode_operations; break; case S_IFDIR: - inode->i_nlink++; + inc_nlink(inode); if(v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else diff --git a/fs/Kconfig b/fs/Kconfig index 4fd9efac29a..1453d2d164f 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -4,6 +4,8 @@ menu "File systems" +if BLOCK + config EXT2_FS tristate "Second extended fs support" help @@ -399,6 +401,8 @@ config ROMFS_FS If you don't know whether you need it, then you don't need it: answer N. +endif + config INOTIFY bool "Inotify file change notification support" default y @@ -530,6 +534,7 @@ config FUSE_FS If you want to develop a userspace FS, or if you want to use a filesystem based on FUSE, answer Y or M. +if BLOCK menu "CD-ROM/DVD Filesystems" config ISO9660_FS @@ -597,7 +602,9 @@ config UDF_NLS depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y) endmenu +endif +if BLOCK menu "DOS/FAT/NT Filesystems" config FAT_FS @@ -782,6 +789,7 @@ config NTFS_RW It is perfectly safe to say N here. endmenu +endif menu "Pseudo filesystems" @@ -939,7 +947,7 @@ menu "Miscellaneous filesystems" config ADFS_FS tristate "ADFS file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help The Acorn Disc Filing System is the standard file system of the RiscOS operating system which runs on Acorn's ARM-based Risc PC @@ -967,7 +975,7 @@ config ADFS_FS_RW config AFFS_FS tristate "Amiga FFS file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help The Fast File System (FFS) is the common file system used on hard disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y @@ -989,7 +997,7 @@ config AFFS_FS config HFS_FS tristate "Apple Macintosh file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL select NLS help If you say Y here, you will be able to mount Macintosh-formatted @@ -1002,6 +1010,7 @@ config HFS_FS config HFSPLUS_FS tristate "Apple Extended HFS file system support" + depends on BLOCK select NLS select NLS_UTF8 help @@ -1015,7 +1024,7 @@ config HFSPLUS_FS config BEFS_FS tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL select NLS help The BeOS File System (BeFS) is the native file system of Be, Inc's @@ -1042,7 +1051,7 @@ config BEFS_DEBUG config BFS_FS tristate "BFS file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help Boot File System (BFS) is a file system used under SCO UnixWare to allow the bootloader access to the kernel image and other important @@ -1064,7 +1073,7 @@ config BFS_FS config EFS_FS tristate "EFS file system support (read only) (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help EFS is an older file system used for non-ISO9660 CD-ROMs and hard disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer @@ -1079,7 +1088,7 @@ config EFS_FS config JFFS_FS tristate "Journalling Flash File System (JFFS) support" - depends on MTD + depends on MTD && BLOCK help JFFS is the Journaling Flash File System developed by Axis Communications in Sweden, aimed at providing a crash/powerdown-safe @@ -1264,6 +1273,7 @@ endchoice config CRAMFS tristate "Compressed ROM file system support (cramfs)" + depends on BLOCK select ZLIB_INFLATE help Saying Y here includes support for CramFs (Compressed ROM File @@ -1283,6 +1293,7 @@ config CRAMFS config VXFS_FS tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" + depends on BLOCK help FreeVxFS is a file system driver that support the VERITAS VxFS(TM) file system format. VERITAS VxFS(TM) is the standard file system @@ -1300,6 +1311,7 @@ config VXFS_FS config HPFS_FS tristate "OS/2 HPFS file system support" + depends on BLOCK help OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS is the file system used for organizing files on OS/2 hard disk @@ -1316,6 +1328,7 @@ config HPFS_FS config QNX4FS_FS tristate "QNX4 file system support (read only)" + depends on BLOCK help This is the file system used by the real-time operating systems QNX 4 and QNX 6 (the latter is also called QNX RTP). @@ -1343,6 +1356,7 @@ config QNX4FS_RW config SYSV_FS tristate "System V/Xenix/V7/Coherent file system support" + depends on BLOCK help SCO, Xenix and Coherent are commercial Unix systems for Intel machines, and Version 7 was used on the DEC PDP-11. Saying Y @@ -1381,6 +1395,7 @@ config SYSV_FS config UFS_FS tristate "UFS file system support (read only)" + depends on BLOCK help BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, OpenBSD and NeXTstep) use a file system called UFS. Some System V @@ -1959,11 +1974,13 @@ config GENERIC_ACL endmenu +if BLOCK menu "Partition Types" source "fs/partitions/Kconfig" endmenu +endif source "fs/nls/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index 46b8cfe497b..819b2a93beb 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -5,12 +5,18 @@ # Rewritten to use lists instead of if-statements. # -obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \ - block_dev.o char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ +obj-y := open.o read_write.o file_table.o super.o \ + char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ - seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ - ioprio.o pnode.o drop_caches.o splice.o sync.o + seq_file.o xattr.o libfs.o fs-writeback.o \ + pnode.o drop_caches.o splice.o sync.o utimes.o + +ifeq ($(CONFIG_BLOCK),y) +obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o +else +obj-y += no-block.o +endif obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_INOTIFY_USER) += inotify_user.o diff --git a/fs/adfs/file.c b/fs/adfs/file.c index 1014b9f2117..6101ea679cb 100644 --- a/fs/adfs/file.c +++ b/fs/adfs/file.c @@ -27,10 +27,12 @@ const struct file_operations adfs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .mmap = generic_file_mmap, .fsync = file_fsync, - .write = generic_file_write, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .sendfile = generic_file_sendfile, }; diff --git a/fs/affs/file.c b/fs/affs/file.c index 3de8590e4f6..05b5e22de75 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -27,8 +27,10 @@ static int affs_file_release(struct inode *inode, struct file *filp); const struct file_operations affs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .open = affs_file_open, .release = affs_file_release, diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 2fc99877cb0..cf8a2cb2850 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -30,7 +30,7 @@ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir); static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); static int afs_d_delete(struct dentry *dentry); static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, - loff_t fpos, ino_t ino, unsigned dtype); + loff_t fpos, u64 ino, unsigned dtype); const struct file_operations afs_dir_file_operations = { .open = afs_dir_open, @@ -409,7 +409,7 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir) * uniquifier through dtype */ static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, - loff_t fpos, ino_t ino, unsigned dtype) + loff_t fpos, u64 ino, unsigned dtype) { struct afs_dir_lookup_cookie *cookie = _cookie; diff --git a/fs/afs/file.c b/fs/afs/file.c index 67d6634101f..2e8c42639ea 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -16,7 +16,6 @@ #include <linux/slab.h> #include <linux/fs.h> #include <linux/pagemap.h> -#include <linux/buffer_head.h> #include "volume.h" #include "vnode.h" #include <rxrpc/call.h> @@ -37,7 +36,6 @@ struct inode_operations afs_file_inode_operations = { const struct address_space_operations afs_fs_aops = { .readpage = afs_file_readpage, - .sync_page = block_sync_page, .set_page_dirty = __set_page_dirty_nobuffers, .releasepage = afs_file_releasepage, .invalidatepage = afs_file_invalidatepage, @@ -15,6 +15,7 @@ #include <linux/aio_abi.h> #include <linux/module.h> #include <linux/syscalls.h> +#include <linux/uio.h> #define DEBUG 0 @@ -414,6 +415,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx) req->ki_retry = NULL; req->ki_dtor = NULL; req->private = NULL; + req->ki_iovec = NULL; INIT_LIST_HEAD(&req->ki_run_list); /* Check if the completion queue has enough free space to @@ -459,6 +461,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) if (req->ki_dtor) req->ki_dtor(req); + if (req->ki_iovec != &req->ki_inline_vec) + kfree(req->ki_iovec); kmem_cache_free(kiocb_cachep, req); ctx->reqs_active--; @@ -671,7 +675,7 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) } if (!(iocb->ki_retried & 0xff)) { - pr_debug("%ld retry: %d of %d\n", iocb->ki_retried, + pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried, iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); } @@ -1004,7 +1008,7 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) pr_debug("added to ring %p at [%lu]\n", iocb, tail); - pr_debug("%ld retries: %d of %d\n", iocb->ki_retried, + pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried, iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); put_rq: /* everything turned out well, dispose of the aiocb. */ @@ -1300,63 +1304,63 @@ asmlinkage long sys_io_destroy(aio_context_t ctx) return -EINVAL; } -/* - * aio_p{read,write} are the default ki_retry methods for - * IO_CMD_P{READ,WRITE}. They maintains kiocb retry state around potentially - * multiple calls to f_op->aio_read(). They loop around partial progress - * instead of returning -EIOCBRETRY because they don't have the means to call - * kick_iocb(). - */ -static ssize_t aio_pread(struct kiocb *iocb) +static void aio_advance_iovec(struct kiocb *iocb, ssize_t ret) { - struct file *file = iocb->ki_filp; - struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - ssize_t ret = 0; - - do { - ret = file->f_op->aio_read(iocb, iocb->ki_buf, - iocb->ki_left, iocb->ki_pos); - /* - * Can't just depend on iocb->ki_left to determine - * whether we are done. This may have been a short read. - */ - if (ret > 0) { - iocb->ki_buf += ret; - iocb->ki_left -= ret; + struct iovec *iov = &iocb->ki_iovec[iocb->ki_cur_seg]; + + BUG_ON(ret <= 0); + + while (iocb->ki_cur_seg < iocb->ki_nr_segs && ret > 0) { + ssize_t this = min((ssize_t)iov->iov_len, ret); + iov->iov_base += this; + iov->iov_len -= this; + iocb->ki_left -= this; + ret -= this; + if (iov->iov_len == 0) { + iocb->ki_cur_seg++; + iov++; } + } - /* - * For pipes and sockets we return once we have some data; for - * regular files we retry till we complete the entire read or - * find that we can't read any more data (e.g short reads). - */ - } while (ret > 0 && iocb->ki_left > 0 && - !S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode)); - - /* This means we must have transferred all that we could */ - /* No need to retry anymore */ - if ((ret == 0) || (iocb->ki_left == 0)) - ret = iocb->ki_nbytes - iocb->ki_left; - - return ret; + /* the caller should not have done more io than what fit in + * the remaining iovecs */ + BUG_ON(ret > 0 && iocb->ki_left == 0); } -/* see aio_pread() */ -static ssize_t aio_pwrite(struct kiocb *iocb) +static ssize_t aio_rw_vect_retry(struct kiocb *iocb) { struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + ssize_t (*rw_op)(struct kiocb *, const struct iovec *, + unsigned long, loff_t); ssize_t ret = 0; + unsigned short opcode; + + if ((iocb->ki_opcode == IOCB_CMD_PREADV) || + (iocb->ki_opcode == IOCB_CMD_PREAD)) { + rw_op = file->f_op->aio_read; + opcode = IOCB_CMD_PREADV; + } else { + rw_op = file->f_op->aio_write; + opcode = IOCB_CMD_PWRITEV; + } do { - ret = file->f_op->aio_write(iocb, iocb->ki_buf, - iocb->ki_left, iocb->ki_pos); - if (ret > 0) { - iocb->ki_buf += ret; - iocb->ki_left -= ret; - } - } while (ret > 0 && iocb->ki_left > 0); + ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg], + iocb->ki_nr_segs - iocb->ki_cur_seg, + iocb->ki_pos); + if (ret > 0) + aio_advance_iovec(iocb, ret); + + /* retry all partial writes. retry partial reads as long as its a + * regular file. */ + } while (ret > 0 && iocb->ki_left > 0 && + (opcode == IOCB_CMD_PWRITEV || + (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode)))); + /* This means we must have transferred all that we could */ + /* No need to retry anymore */ if ((ret == 0) || (iocb->ki_left == 0)) ret = iocb->ki_nbytes - iocb->ki_left; @@ -1383,6 +1387,38 @@ static ssize_t aio_fsync(struct kiocb *iocb) return ret; } +static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb) +{ + ssize_t ret; + + ret = rw_copy_check_uvector(type, (struct iovec __user *)kiocb->ki_buf, + kiocb->ki_nbytes, 1, + &kiocb->ki_inline_vec, &kiocb->ki_iovec); + if (ret < 0) + goto out; + + kiocb->ki_nr_segs = kiocb->ki_nbytes; + kiocb->ki_cur_seg = 0; + /* ki_nbytes/left now reflect bytes instead of segs */ + kiocb->ki_nbytes = ret; + kiocb->ki_left = ret; + + ret = 0; +out: + return ret; +} + +static ssize_t aio_setup_single_vector(struct kiocb *kiocb) +{ + kiocb->ki_iovec = &kiocb->ki_inline_vec; + kiocb->ki_iovec->iov_base = kiocb->ki_buf; + kiocb->ki_iovec->iov_len = kiocb->ki_left; + kiocb->ki_nr_segs = 1; + kiocb->ki_cur_seg = 0; + kiocb->ki_nbytes = kiocb->ki_left; + return 0; +} + /* * aio_setup_iocb: * Performs the initial checks and aio retry method @@ -1405,9 +1441,12 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb) ret = security_file_permission(file, MAY_READ); if (unlikely(ret)) break; + ret = aio_setup_single_vector(kiocb); + if (ret) + break; ret = -EINVAL; if (file->f_op->aio_read) - kiocb->ki_retry = aio_pread; + kiocb->ki_retry = aio_rw_vect_retry; break; case IOCB_CMD_PWRITE: ret = -EBADF; @@ -1420,9 +1459,40 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb) ret = security_file_permission(file, MAY_WRITE); if (unlikely(ret)) break; + ret = aio_setup_single_vector(kiocb); + if (ret) + break; + ret = -EINVAL; + if (file->f_op->aio_write) + kiocb->ki_retry = aio_rw_vect_retry; + break; + case IOCB_CMD_PREADV: + ret = -EBADF; + if (unlikely(!(file->f_mode & FMODE_READ))) + break; + ret = security_file_permission(file, MAY_READ); + if (unlikely(ret)) + break; + ret = aio_setup_vectored_rw(READ, kiocb); + if (ret) + break; + ret = -EINVAL; + if (file->f_op->aio_read) + kiocb->ki_retry = aio_rw_vect_retry; + break; + case IOCB_CMD_PWRITEV: + ret = -EBADF; + if (unlikely(!(file->f_mode & FMODE_WRITE))) + break; + ret = security_file_permission(file, MAY_WRITE); + if (unlikely(ret)) + break; + ret = aio_setup_vectored_rw(WRITE, kiocb); + if (ret) + break; ret = -EINVAL; if (file->f_op->aio_write) - kiocb->ki_retry = aio_pwrite; + kiocb->ki_retry = aio_rw_vect_retry; break; case IOCB_CMD_FDSYNC: ret = -EINVAL; diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9cac08d6a87..368a1c33a3c 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -414,7 +414,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry) dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL; autofs_hash_delete(ent); - dir->i_nlink--; + drop_nlink(dir); d_drop(dentry); unlock_kernel(); @@ -466,7 +466,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) ent->dentry = dentry; autofs_hash_insert(dh,ent); - dir->i_nlink++; + inc_nlink(dir); d_instantiate(dentry, iget(dir->i_sb,ino)); unlock_kernel(); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 563ef9d7da9..c1493524da4 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -638,7 +638,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) dput(ino->dentry); dentry->d_inode->i_size = 0; - dentry->d_inode->i_nlink = 0; + clear_nlink(dentry->d_inode); dir->i_mtime = CURRENT_TIME; @@ -673,10 +673,10 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) } dput(ino->dentry); dentry->d_inode->i_size = 0; - dentry->d_inode->i_nlink = 0; + clear_nlink(dentry->d_inode); if (dir->i_nlink) - dir->i_nlink--; + drop_nlink(dir); return 0; } @@ -713,7 +713,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (p_ino && dentry->d_parent != dentry) atomic_inc(&p_ino->count); ino->inode = inode; - dir->i_nlink++; + inc_nlink(dir); dir->i_mtime = CURRENT_TIME; return 0; diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 80599ae3396..34e6d7b220c 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -40,8 +40,6 @@ static const struct file_operations bad_file_ops = .aio_fsync = EIO_ERROR, .fasync = EIO_ERROR, .lock = EIO_ERROR, - .readv = EIO_ERROR, - .writev = EIO_ERROR, .sendfile = EIO_ERROR, .sendpage = EIO_ERROR, .get_unmapped_area = EIO_ERROR, diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index dcf04cb1328..a650f1d0b85 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -117,8 +117,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode, err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino); if (err) { - inode->i_nlink--; - mark_inode_dirty(inode); + inode_dec_link_count(inode); iput(inode); unlock_kernel(); return err; @@ -164,7 +163,7 @@ static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new unlock_kernel(); return err; } - inode->i_nlink++; + inc_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); atomic_inc(&inode->i_count); @@ -196,9 +195,8 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry) mark_buffer_dirty(bh); dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); - inode->i_nlink--; inode->i_ctime = dir->i_ctime; - mark_inode_dirty(inode); + inode_dec_link_count(inode); error = 0; out_brelse: @@ -249,9 +247,8 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry, old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(old_dir); if (new_inode) { - new_inode->i_nlink--; new_inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(new_inode); + inode_dec_link_count(new_inode); } mark_buffer_dirty(old_bh); error = 0; diff --git a/fs/bfs/file.c b/fs/bfs/file.c index 3d5aca28a0a..a9164a87f8d 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -19,8 +19,10 @@ const struct file_operations bfs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, }; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6eb48e1446e..06435f3665f 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -46,7 +46,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); -extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); #ifndef elf_addr_t #define elf_addr_t unsigned long @@ -1152,11 +1151,23 @@ static int dump_write(struct file *file, const void *addr, int nr) static int dump_seek(struct file *file, loff_t off) { - if (file->f_op->llseek) { - if (file->f_op->llseek(file, off, 0) != off) + if (file->f_op->llseek && file->f_op->llseek != no_llseek) { + if (file->f_op->llseek(file, off, 1) != off) return 0; - } else - file->f_pos = off; + } else { + char *buf = (char *)get_zeroed_page(GFP_KERNEL); + if (!buf) + return 0; + while (off > 0) { + unsigned long n = off; + if (n > PAGE_SIZE) + n = PAGE_SIZE; + if (!dump_write(file, buf, n)) + return 0; + off -= n; + } + free_page((unsigned long)buf); + } return 1; } @@ -1204,30 +1215,35 @@ static int notesize(struct memelfnote *en) return sz; } -#define DUMP_WRITE(addr, nr) \ - do { if (!dump_write(file, (addr), (nr))) return 0; } while(0) -#define DUMP_SEEK(off) \ - do { if (!dump_seek(file, (off))) return 0; } while(0) +#define DUMP_WRITE(addr, nr, foffset) \ + do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0) -static int writenote(struct memelfnote *men, struct file *file) +static int alignfile(struct file *file, loff_t *foffset) { - struct elf_note en; + char buf[4] = { 0, }; + DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset); + return 1; +} +static int writenote(struct memelfnote *men, struct file *file, + loff_t *foffset) +{ + struct elf_note en; en.n_namesz = strlen(men->name) + 1; en.n_descsz = men->datasz; en.n_type = men->type; - DUMP_WRITE(&en, sizeof(en)); - DUMP_WRITE(men->name, en.n_namesz); - /* XXX - cast from long long to long to avoid need for libgcc.a */ - DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ - DUMP_WRITE(men->data, men->datasz); - DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ + DUMP_WRITE(&en, sizeof(en), foffset); + DUMP_WRITE(men->name, en.n_namesz, foffset); + if (!alignfile(file, foffset)) + return 0; + DUMP_WRITE(men->data, men->datasz, foffset); + if (!alignfile(file, foffset)) + return 0; return 1; } #undef DUMP_WRITE -#undef DUMP_SEEK #define DUMP_WRITE(addr, nr) \ if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ @@ -1427,7 +1443,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) int i; struct vm_area_struct *vma; struct elfhdr *elf = NULL; - loff_t offset = 0, dataoff; + loff_t offset = 0, dataoff, foffset; unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; int numnote; struct memelfnote *notes = NULL; @@ -1570,7 +1586,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) DUMP_WRITE(&phdr, sizeof(phdr)); } - /* Page-align dumped data */ + foffset = offset; + dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* Write program headers for segments dump */ @@ -1595,6 +1612,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) phdr.p_align = ELF_EXEC_PAGESIZE; DUMP_WRITE(&phdr, sizeof(phdr)); + foffset += sizeof(phdr); } #ifdef ELF_CORE_WRITE_EXTRA_PHDRS @@ -1603,7 +1621,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) /* write out the notes section */ for (i = 0; i < numnote; i++) - if (!writenote(notes + i, file)) + if (!writenote(notes + i, file, &foffset)) goto end_coredump; /* write out the thread status notes section */ @@ -1612,11 +1630,12 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) list_entry(t, struct elf_thread_status, list); for (i = 0; i < tmp->num_notes; i++) - if (!writenote(&tmp->notes[i], file)) + if (!writenote(&tmp->notes[i], file, &foffset)) goto end_coredump; } - - DUMP_SEEK(dataoff); + + /* Align to page */ + DUMP_SEEK(dataoff - foffset); for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { unsigned long addr; @@ -1632,10 +1651,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) if (get_user_pages(current, current->mm, addr, 1, 0, 1, &page, &vma) <= 0) { - DUMP_SEEK(file->f_pos + PAGE_SIZE); + DUMP_SEEK(PAGE_SIZE); } else { if (page == ZERO_PAGE(addr)) { - DUMP_SEEK(file->f_pos + PAGE_SIZE); + DUMP_SEEK(PAGE_SIZE); } else { void *kaddr; flush_cache_page(vma, addr, @@ -1659,13 +1678,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) ELF_CORE_WRITE_EXTRA_DATA; #endif - if (file->f_pos != offset) { - /* Sanity check */ - printk(KERN_WARNING - "elf_core_dump: file->f_pos (%Ld) != offset (%Ld)\n", - file->f_pos, offset); - } - end_coredump: set_fs(fs); @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Jens Axboe <axboe@suse.de> + * Copyright (C) 2001 Jens Axboe <axboe@kernel.dk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -1142,7 +1142,7 @@ static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale) struct biovec_slab *bp = bvec_slabs + i; mempool_t **bvp = bs->bvec_pools + i; - if (i >= scale) + if (pool_entries > 1 && i >= scale) pool_entries >>= 1; *bvp = mempool_create_slab_pool(pool_entries, bp->slab); diff --git a/fs/block_dev.c b/fs/block_dev.c index 4346468139e..bc8f27cc448 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -17,11 +17,13 @@ #include <linux/module.h> #include <linux/blkpg.h> #include <linux/buffer_head.h> +#include <linux/writeback.h> #include <linux/mpage.h> #include <linux/mount.h> #include <linux/uio.h> #include <linux/namei.h> #include <asm/uaccess.h> +#include "internal.h" struct bdev_inode { struct block_device bdev; @@ -1152,22 +1154,6 @@ static int blkdev_close(struct inode * inode, struct file * filp) return blkdev_put(bdev); } -static ssize_t blkdev_file_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count }; - - return generic_file_write_nolock(file, &local_iov, 1, ppos); -} - -static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) -{ - struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count }; - - return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); -} - static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) { return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); @@ -1187,18 +1173,16 @@ const struct file_operations def_blk_fops = { .open = blkdev_open, .release = blkdev_close, .llseek = block_llseek, - .read = generic_file_read, - .write = blkdev_file_write, + .read = do_sync_read, + .write = do_sync_write, .aio_read = generic_file_aio_read, - .aio_write = blkdev_file_aio_write, + .aio_write = generic_file_aio_write_nolock, .mmap = generic_file_mmap, .fsync = block_fsync, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_blkdev_ioctl, #endif - .readv = generic_file_readv, - .writev = generic_file_write_nolock, .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, @@ -1313,3 +1297,24 @@ void close_bdev_excl(struct block_device *bdev) } EXPORT_SYMBOL(close_bdev_excl); + +int __invalidate_device(struct block_device *bdev) +{ + struct super_block *sb = get_super(bdev); + int res = 0; + + if (sb) { + /* + * no need to lock the super, get_super holds the + * read mutex so the filesystem cannot go away + * under us (->put_super runs with the write lock + * hold). + */ + shrink_dcache_sb(sb); + res = invalidate_inodes(sb); + drop_super(sb); + } + invalidate_bdev(bdev, 0); + return res; +} +EXPORT_SYMBOL(__invalidate_device); diff --git a/fs/buffer.c b/fs/buffer.c index 3b6d701073e..16cfbcd254f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -159,31 +159,6 @@ int sync_blockdev(struct block_device *bdev) } EXPORT_SYMBOL(sync_blockdev); -static void __fsync_super(struct super_block *sb) -{ - sync_inodes_sb(sb, 0); - DQUOT_SYNC(sb); - lock_super(sb); - if (sb->s_dirt && sb->s_op->write_super) - sb->s_op->write_super(sb); - unlock_super(sb); - if (sb->s_op->sync_fs) - sb->s_op->sync_fs(sb, 1); - sync_blockdev(sb->s_bdev); - sync_inodes_sb(sb, 1); -} - -/* - * Write out and wait upon all dirty data associated with this - * superblock. Filesystem data as well as the underlying block - * device. Takes the superblock lock. - */ -int fsync_super(struct super_block *sb) -{ - __fsync_super(sb); - return sync_blockdev(sb->s_bdev); -} - /* * Write out and wait upon all dirty data associated with this * device. Filesystem data as well as the underlying block @@ -260,118 +235,6 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb) EXPORT_SYMBOL(thaw_bdev); /* - * sync everything. Start out by waking pdflush, because that writes back - * all queues in parallel. - */ -static void do_sync(unsigned long wait) -{ - wakeup_pdflush(0); - sync_inodes(0); /* All mappings, inodes and their blockdevs */ - DQUOT_SYNC(NULL); - sync_supers(); /* Write the superblocks */ - sync_filesystems(0); /* Start syncing the filesystems */ - sync_filesystems(wait); /* Waitingly sync the filesystems */ - sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ - if (!wait) - printk("Emergency Sync complete\n"); - if (unlikely(laptop_mode)) - laptop_sync_completion(); -} - -asmlinkage long sys_sync(void) -{ - do_sync(1); - return 0; -} - -void emergency_sync(void) -{ - pdflush_operation(do_sync, 0); -} - -/* - * Generic function to fsync a file. - * - * filp may be NULL if called via the msync of a vma. - */ - -int file_fsync(struct file *filp, struct dentry *dentry, int datasync) -{ - struct inode * inode = dentry->d_inode; - struct super_block * sb; - int ret, err; - - /* sync the inode to buffers */ - ret = write_inode_now(inode, 0); - - /* sync the superblock to buffers */ - sb = inode->i_sb; - lock_super(sb); - if (sb->s_op->write_super) - sb->s_op->write_super(sb); - unlock_super(sb); - - /* .. finally sync the buffers to disk */ - err = sync_blockdev(sb->s_bdev); - if (!ret) - ret = err; - return ret; -} - -long do_fsync(struct file *file, int datasync) -{ - int ret; - int err; - struct address_space *mapping = file->f_mapping; - - if (!file->f_op || !file->f_op->fsync) { - /* Why? We can still call filemap_fdatawrite */ - ret = -EINVAL; - goto out; - } - - ret = filemap_fdatawrite(mapping); - - /* - * We need to protect against concurrent writers, which could cause - * livelocks in fsync_buffers_list(). - */ - mutex_lock(&mapping->host->i_mutex); - err = file->f_op->fsync(file, file->f_dentry, datasync); - if (!ret) - ret = err; - mutex_unlock(&mapping->host->i_mutex); - err = filemap_fdatawait(mapping); - if (!ret) - ret = err; -out: - return ret; -} - -static long __do_fsync(unsigned int fd, int datasync) -{ - struct file *file; - int ret = -EBADF; - - file = fget(fd); - if (file) { - ret = do_fsync(file, datasync); - fput(file); - } - return ret; -} - -asmlinkage long sys_fsync(unsigned int fd) -{ - return __do_fsync(fd, 0); -} - -asmlinkage long sys_fdatasync(unsigned int fd) -{ - return __do_fsync(fd, 1); -} - -/* * Various filesystems appear to want __find_get_block to be non-blocking. * But it's the page lock which protects the buffers. To get around this, * we get exclusion from try_to_free_buffers with the blockdev mapping's @@ -1551,35 +1414,6 @@ static void discard_buffer(struct buffer_head * bh) } /** - * try_to_release_page() - release old fs-specific metadata on a page - * - * @page: the page which the kernel is trying to free - * @gfp_mask: memory allocation flags (and I/O mode) - * - * The address_space is to try to release any data against the page - * (presumably at page->private). If the release was successful, return `1'. - * Otherwise return zero. - * - * The @gfp_mask argument specifies whether I/O may be performed to release - * this page (__GFP_IO), and whether the call may block (__GFP_WAIT). - * - * NOTE: @gfp_mask may go away, and this function may become non-blocking. - */ -int try_to_release_page(struct page *page, gfp_t gfp_mask) -{ - struct address_space * const mapping = page->mapping; - - BUG_ON(!PageLocked(page)); - if (PageWriteback(page)) - return 0; - - if (mapping && mapping->a_ops->releasepage) - return mapping->a_ops->releasepage(page, gfp_mask); - return try_to_free_buffers(page); -} -EXPORT_SYMBOL(try_to_release_page); - -/** * block_invalidatepage - invalidate part of all of a buffer-backed page * * @page: the page which is affected @@ -1630,14 +1464,6 @@ out: } EXPORT_SYMBOL(block_invalidatepage); -void do_invalidatepage(struct page *page, unsigned long offset) -{ - void (*invalidatepage)(struct page *, unsigned long); - invalidatepage = page->mapping->a_ops->invalidatepage ? : - block_invalidatepage; - (*invalidatepage)(page, offset); -} - /* * We attach and possibly dirty the buffers atomically wrt * __set_page_dirty_buffers() via private_lock. try_to_free_buffers diff --git a/fs/char_dev.c b/fs/char_dev.c index 1f3285affa3..a885f46ca00 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -24,6 +24,7 @@ #ifdef CONFIG_KMOD #include <linux/kmod.h> #endif +#include "internal.h" /* * capabilities for /dev/mem, /dev/kmem and similar directly mappable character diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 22bcf4d7e7a..c00c654f2e1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -480,25 +480,13 @@ cifs_get_sb(struct file_system_type *fs_type, return simple_set_mnt(mnt, sb); } -static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, - unsigned long nr_segs, loff_t *ppos) -{ - struct inode *inode = file->f_dentry->d_inode; - ssize_t written; - - written = generic_file_writev(file, iov, nr_segs, ppos); - if (!CIFS_I(inode)->clientCanCacheAll) - filemap_fdatawrite(inode->i_mapping); - return written; -} - -static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) +static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct inode *inode = iocb->ki_filp->f_dentry->d_inode; ssize_t written; - written = generic_file_aio_write(iocb, buf, count, pos); + written = generic_file_aio_write(iocb, iov, nr_segs, pos); if (!CIFS_I(inode)->clientCanCacheAll) filemap_fdatawrite(inode->i_mapping); return written; @@ -577,8 +565,6 @@ struct inode_operations cifs_symlink_inode_ops = { const struct file_operations cifs_file_ops = { .read = do_sync_read, .write = do_sync_write, - .readv = generic_file_readv, - .writev = cifs_file_writev, .aio_read = generic_file_aio_read, .aio_write = cifs_file_aio_write, .open = cifs_open, @@ -620,8 +606,6 @@ const struct file_operations cifs_file_direct_ops = { const struct file_operations cifs_file_nobrl_ops = { .read = do_sync_read, .write = do_sync_write, - .readv = generic_file_readv, - .writev = cifs_file_writev, .aio_read = generic_file_aio_read, .aio_write = cifs_file_aio_write, .open = cifs_open, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 0e9ba0b9d71..c78762051da 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -772,12 +772,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) separator[1] = 0; memset(vol->source_rfc1001_name,0x20,15); - for(i=0;i < strnlen(system_utsname.nodename,15);i++) { + for(i=0;i < strnlen(utsname()->nodename,15);i++) { /* does not have to be a perfect mapping since the field is informational, only used for servers that do not support port 445 and it can be overridden at mount time */ vol->source_rfc1001_name[i] = - toupper(system_utsname.nodename[i]); + toupper(utsname()->nodename[i]); } vol->source_rfc1001_name[15] = 0; /* null target name indicates to use *SMBSERVR default called name @@ -2153,7 +2153,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, + cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; @@ -2180,8 +2180,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, } strcpy(bcc_ptr, "Linux version "); bcc_ptr += strlen("Linux version "); - strcpy(bcc_ptr, system_utsname.release); - bcc_ptr += strlen(system_utsname.release) + 1; + strcpy(bcc_ptr, utsname()->release); + bcc_ptr += strlen(utsname()->release) + 1; strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; } @@ -2445,7 +2445,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, + cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; /* null terminate Linux version */ @@ -2462,8 +2462,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, } else { /* ASCII */ strcpy(bcc_ptr, "Linux version "); bcc_ptr += strlen("Linux version "); - strcpy(bcc_ptr, system_utsname.release); - bcc_ptr += strlen(system_utsname.release) + 1; + strcpy(bcc_ptr, utsname()->release); + bcc_ptr += strlen(utsname()->release) + 1; strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; bcc_ptr++; /* empty domain field */ @@ -2836,7 +2836,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, + cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; /* null term version string */ @@ -2888,8 +2888,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, strcpy(bcc_ptr, "Linux version "); bcc_ptr += strlen("Linux version "); - strcpy(bcc_ptr, system_utsname.release); - bcc_ptr += strlen(system_utsname.release) + 1; + strcpy(bcc_ptr, utsname()->release); + bcc_ptr += strlen(utsname()->release) + 1; strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; bcc_ptr++; /* null domain */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ddb012a6802..976a691c5a6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -25,7 +25,6 @@ #include <linux/backing-dev.h> #include <linux/stat.h> #include <linux/fcntl.h> -#include <linux/mpage.h> #include <linux/pagemap.h> #include <linux/pagevec.h> #include <linux/smp_lock.h> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b88147c1dc2..6b90ef98e4c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -19,7 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> -#include <linux/buffer_head.h> #include <linux/stat.h> #include <linux/pagemap.h> #include <asm/div64.h> @@ -591,7 +590,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) if (!rc) { if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } else if (rc == -ENOENT) { d_drop(direntry); } else if (rc == -ETXTBSY) { @@ -610,7 +609,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } } else if (rc == -EACCES) { /* try only if r/o attribute set in local lookup data? */ @@ -664,7 +663,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } else if (rc == -ETXTBSY) { int oplock = FALSE; __u16 netfid; @@ -685,7 +684,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } /* BB if rc = -ETXTBUSY goto the rename logic BB */ } @@ -736,7 +735,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) cFYI(1, ("cifs_mkdir returned 0x%x", rc)); d_drop(direntry); } else { - inode->i_nlink++; + inc_nlink(inode); if (pTcon->ses->capabilities & CAP_UNIX) rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,xid); @@ -817,9 +816,9 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - inode->i_nlink--; + drop_nlink(inode); i_size_write(direntry->d_inode,0); - direntry->d_inode->i_nlink = 0; + clear_nlink(direntry->d_inode); } cifsInode = CIFS_I(direntry->d_inode); diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index b0ea6687ab5..e34c7db00f6 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -22,7 +22,6 @@ */ #include <linux/fs.h> -#include <linux/ext2_fs.h> #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" @@ -74,7 +73,7 @@ int cifs_ioctl (struct inode * inode, struct file * filep, } break; #ifdef CONFIG_CIFS_POSIX - case EXT2_IOC_GETFLAGS: + case FS_IOC_GETFLAGS: if(CIFS_UNIX_EXTATTR_CAP & caps) { if (pSMBFile == NULL) break; @@ -82,12 +81,12 @@ int cifs_ioctl (struct inode * inode, struct file * filep, &ExtAttrBits, &ExtAttrMask); if(rc == 0) rc = put_user(ExtAttrBits & - EXT2_FL_USER_VISIBLE, + FS_FL_USER_VISIBLE, (int __user *)arg); } break; - case EXT2_IOC_SETFLAGS: + case FS_IOC_SETFLAGS: if(CIFS_UNIX_EXTATTR_CAP & caps) { if(get_user(ExtAttrBits,(int __user *)arg)) { rc = -EFAULT; diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index d1705ab8136..22b4c35dcfe 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -111,7 +111,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32, nls_cp); bcc_ptr += 2 * bytes_ret; - bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release, 32, nls_cp); bcc_ptr += 2 * bytes_ret; bcc_ptr += 2; /* trailing null */ @@ -158,8 +158,8 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, strcpy(bcc_ptr, "Linux version "); bcc_ptr += strlen("Linux version "); - strcpy(bcc_ptr, system_utsname.release); - bcc_ptr += strlen(system_utsname.release) + 1; + strcpy(bcc_ptr, init_utsname()->release); + bcc_ptr += strlen(init_utsname()->release) + 1; strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 8651ea6a23b..0102b28a15f 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -304,7 +304,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode, coda_dir_changed(dir_inode, 0); atomic_inc(&inode->i_count); d_instantiate(de, inode); - inode->i_nlink++; + inc_nlink(inode); out: unlock_kernel(); @@ -367,7 +367,7 @@ int coda_unlink(struct inode *dir, struct dentry *de) } coda_dir_changed(dir, 0); - de->d_inode->i_nlink--; + drop_nlink(de->d_inode); unlock_kernel(); return 0; @@ -394,7 +394,7 @@ int coda_rmdir(struct inode *dir, struct dentry *de) } coda_dir_changed(dir, -1); - de->d_inode->i_nlink--; + drop_nlink(de->d_inode); d_delete(de); unlock_kernel(); diff --git a/fs/compat.c b/fs/compat.c index ce982f6e8c8..4d3fbcb2ddb 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -44,7 +44,7 @@ #include <linux/nfsd/syscall.h> #include <linux/personality.h> #include <linux/rwsem.h> -#include <linux/acct.h> +#include <linux/tsacct_kern.h> #include <linux/mm.h> #include <net/sock.h> /* siocdevprivate_ioctl */ @@ -52,8 +52,7 @@ #include <asm/uaccess.h> #include <asm/mmu_context.h> #include <asm/ioctls.h> - -extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); +#include "internal.h" int compat_log = 1; @@ -69,6 +68,8 @@ int compat_printk(const char *fmt, ...) return ret; } +#include "read_write.h" + /* * Not all architectures have sys_utime, so implement this in terms * of sys_utimes. @@ -313,9 +314,6 @@ out: #define IOCTL_HASHSIZE 256 static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; -extern struct ioctl_trans ioctl_start[]; -extern int ioctl_table_size; - static inline unsigned long ioctl32_hash(unsigned long cmd) { return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; @@ -838,8 +836,6 @@ static int do_nfs4_super_data_conv(void *raw_data) return 0; } -extern int copy_mount_options (const void __user *, unsigned long *); - #define SMBFS_NAME "smbfs" #define NCPFS_NAME "ncpfs" #define NFS4_NAME "nfs4" @@ -918,20 +914,24 @@ struct compat_readdir_callback { }; static int compat_fillonedir(void *__buf, const char *name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct compat_readdir_callback *buf = __buf; struct compat_old_linux_dirent __user *dirent; + compat_ulong_t d_ino; if (buf->result) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; buf->result++; dirent = buf->dirent; if (!access_ok(VERIFY_WRITE, dirent, (unsigned long)(dirent->d_name + namlen + 1) - (unsigned long)dirent)) goto efault; - if ( __put_user(ino, &dirent->d_ino) || + if ( __put_user(d_ino, &dirent->d_ino) || __put_user(offset, &dirent->d_offset) || __put_user(namlen, &dirent->d_namlen) || __copy_to_user(dirent->d_name, name, namlen) || @@ -982,22 +982,26 @@ struct compat_getdents_callback { }; static int compat_filldir(void *__buf, const char *name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct compat_linux_dirent __user * dirent; struct compat_getdents_callback *buf = __buf; + compat_ulong_t d_ino; int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; dirent = buf->previous; if (dirent) { if (__put_user(offset, &dirent->d_off)) goto efault; } dirent = buf->current_dir; - if (__put_user(ino, &dirent->d_ino)) + if (__put_user(d_ino, &dirent->d_ino)) goto efault; if (__put_user(reclen, &dirent->d_reclen)) goto efault; @@ -1068,7 +1072,7 @@ struct compat_getdents_callback64 { }; static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, - ino_t ino, unsigned int d_type) + u64 ino, unsigned int d_type) { struct linux_dirent64 __user *dirent; struct compat_getdents_callback64 *buf = __buf; @@ -1153,9 +1157,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, const struct compat_iovec __user *uvector, unsigned long nr_segs, loff_t *pos) { - typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); - typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); - compat_ssize_t tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov=iovstack, *vector; @@ -1238,39 +1239,18 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, fnv = NULL; if (type == READ) { fn = file->f_op->read; - fnv = file->f_op->readv; + fnv = file->f_op->aio_read; } else { fn = (io_fn_t)file->f_op->write; - fnv = file->f_op->writev; - } - if (fnv) { - ret = fnv(file, iov, nr_segs, pos); - goto out; + fnv = file->f_op->aio_write; } - /* Do it by hand, with file-ops */ - ret = 0; - vector = iov; - while (nr_segs > 0) { - void __user * base; - size_t len; - ssize_t nr; - - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - nr = fn(file, base, len, pos); + if (fnv) + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, + pos, fnv); + else + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); - if (nr < 0) { - if (!ret) ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } out: if (iov != iovstack) kfree(iov); @@ -1298,7 +1278,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign goto out; ret = -EINVAL; - if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) goto out; ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); @@ -1321,7 +1301,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig goto out; ret = -EINVAL; - if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) goto out; ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 4063a939697..27ca1aa3056 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -40,15 +40,11 @@ #include <linux/if_pppox.h> #include <linux/mtio.h> #include <linux/cdrom.h> -#include <linux/loop.h> #include <linux/auto_fs.h> #include <linux/auto_fs4.h> #include <linux/tty.h> #include <linux/vt_kern.h> #include <linux/fb.h> -#include <linux/ext2_fs.h> -#include <linux/ext3_jbd.h> -#include <linux/ext3_fs.h> #include <linux/videodev.h> #include <linux/netdevice.h> #include <linux/raw.h> @@ -60,12 +56,10 @@ #include <linux/pci.h> #include <linux/module.h> #include <linux/serial.h> -#include <linux/reiserfs_fs.h> #include <linux/if_tun.h> #include <linux/ctype.h> #include <linux/ioctl32.h> #include <linux/syscalls.h> -#include <linux/ncp_fs.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <linux/wireless.h> @@ -113,7 +107,6 @@ #include <linux/nbd.h> #include <linux/random.h> #include <linux/filter.h> -#include <linux/msdos_fs.h> #include <linux/pktcdvd.h> #include <linux/hiddev.h> @@ -124,21 +117,6 @@ #include <linux/dvb/video.h> #include <linux/lp.h> -/* Aiee. Someone does not find a difference between int and long */ -#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) -#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) -#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) -#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) -#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) -#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) -#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) -#ifdef CONFIG_JBD_DEBUG -#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) -#endif - -#define EXT2_IOC32_GETVERSION _IOR('v', 1, int) -#define EXT2_IOC32_SETVERSION _IOW('v', 2, int) - static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *f) { @@ -176,34 +154,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } -static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - /* These are just misnamed, they actually get/put from/to user an int */ - switch (cmd) { - case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; - case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; - case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; - case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; - } - return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); -} - -static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - /* These are just misnamed, they actually get/put from/to user an int */ - switch (cmd) { - case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break; - case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break; - case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break; - case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break; - case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break; -#ifdef CONFIG_JBD_DEBUG - case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break; -#endif - } - return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); -} - struct compat_video_event { int32_t type; compat_time_t timestamp; @@ -694,6 +644,7 @@ out: } #endif +#ifdef CONFIG_BLOCK struct hd_geometry32 { unsigned char heads; unsigned char sectors; @@ -918,6 +869,7 @@ static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) } return err; } +#endif /* CONFIG_BLOCK */ struct sock_fprog32 { unsigned short len; @@ -1041,6 +993,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) } +#ifdef CONFIG_BLOCK struct mtget32 { compat_long_t mt_type; compat_long_t mt_resid; @@ -1213,73 +1166,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar return err; } - -struct loop_info32 { - compat_int_t lo_number; /* ioctl r/o */ - compat_dev_t lo_device; /* ioctl r/o */ - compat_ulong_t lo_inode; /* ioctl r/o */ - compat_dev_t lo_rdevice; /* ioctl r/o */ - compat_int_t lo_offset; - compat_int_t lo_encrypt_type; - compat_int_t lo_encrypt_key_size; /* ioctl w/o */ - compat_int_t lo_flags; /* ioctl r/o */ - char lo_name[LO_NAME_SIZE]; - unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ - compat_ulong_t lo_init[2]; - char reserved[4]; -}; - -static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - struct loop_info l; - struct loop_info32 __user *ul; - int err = -EINVAL; - - ul = compat_ptr(arg); - switch(cmd) { - case LOOP_SET_STATUS: - err = get_user(l.lo_number, &ul->lo_number); - err |= __get_user(l.lo_device, &ul->lo_device); - err |= __get_user(l.lo_inode, &ul->lo_inode); - err |= __get_user(l.lo_rdevice, &ul->lo_rdevice); - err |= __copy_from_user(&l.lo_offset, &ul->lo_offset, - 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); - if (err) { - err = -EFAULT; - } else { - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&l); - set_fs (old_fs); - } - break; - case LOOP_GET_STATUS: - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&l); - set_fs (old_fs); - if (!err) { - err = put_user(l.lo_number, &ul->lo_number); - err |= __put_user(l.lo_device, &ul->lo_device); - err |= __put_user(l.lo_inode, &ul->lo_inode); - err |= __put_user(l.lo_rdevice, &ul->lo_rdevice); - err |= __copy_to_user(&ul->lo_offset, &l.lo_offset, - (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); - if (err) - err = -EFAULT; - } - break; - default: { - static int count; - if (++count <= 20) - printk("%s: Unknown loop ioctl cmd, fd(%d) " - "cmd(%08x) arg(%08lx)\n", - __FUNCTION__, fd, cmd, arg); - } - } - return err; -} - -extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); +#endif /* CONFIG_BLOCK */ #ifdef CONFIG_VT @@ -1607,6 +1494,7 @@ ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) return -EINVAL; } +#ifdef CONFIG_BLOCK static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg) { /* The mkswap binary hard codes it to Intel value :-((( */ @@ -1641,12 +1529,14 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar return sys_ioctl(fd, cmd, (unsigned long)a); } +#endif static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) { return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); } +#ifdef CONFIG_BLOCK /* Fix sizeof(sizeof()) breakage */ #define BLKBSZGET_32 _IOR(0x12,112,int) #define BLKBSZSET_32 _IOW(0x12,113,int) @@ -1667,6 +1557,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, { return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg)); } +#endif /* Bluetooth ioctls */ #define HCIUARTSETPROTO _IOW('U', 200, int) @@ -1687,6 +1578,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, #define HIDPGETCONNLIST _IOR('H', 210, int) #define HIDPGETCONNINFO _IOR('H', 211, int) +#ifdef CONFIG_BLOCK struct floppy_struct32 { compat_uint_t size; compat_uint_t sect; @@ -2011,6 +1903,7 @@ out: kfree(karg); return err; } +#endif struct mtd_oob_buf32 { u_int32_t start; @@ -2052,61 +1945,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } -#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) -#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) - -static long -put_dirent32 (struct dirent *d, struct compat_dirent __user *d32) -{ - if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) - return -EFAULT; - - __put_user(d->d_ino, &d32->d_ino); - __put_user(d->d_off, &d32->d_off); - __put_user(d->d_reclen, &d32->d_reclen); - if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) - return -EFAULT; - - return 0; -} - -static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg) -{ - struct compat_dirent __user *p = compat_ptr(arg); - int ret; - mm_segment_t oldfs = get_fs(); - struct dirent d[2]; - - switch(cmd) - { - case VFAT_IOCTL_READDIR_BOTH32: - cmd = VFAT_IOCTL_READDIR_BOTH; - break; - case VFAT_IOCTL_READDIR_SHORT32: - cmd = VFAT_IOCTL_READDIR_SHORT; - break; - } - - set_fs(KERNEL_DS); - ret = sys_ioctl(fd,cmd,(unsigned long)&d); - set_fs(oldfs); - if (ret >= 0) { - ret |= put_dirent32(&d[0], p); - ret |= put_dirent32(&d[1], p + 1); - } - return ret; -} - -#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int) - -static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr) -{ - if (cmd == REISERFS_IOC_UNPACK32) - cmd = REISERFS_IOC_UNPACK; - - return sys_ioctl(fd,cmd,ptr); -} - +#ifdef CONFIG_BLOCK struct raw32_config_request { compat_int_t raw_minor; @@ -2171,6 +2010,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) } return ret; } +#endif /* CONFIG_BLOCK */ struct serial_struct32 { compat_int_t type; @@ -2507,193 +2347,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) } } -#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) -struct ncp_ioctl_request_32 { - u32 function; - u32 size; - compat_caddr_t data; -}; - -struct ncp_fs_info_v2_32 { - s32 version; - u32 mounted_uid; - u32 connection; - u32 buffer_size; - - u32 volume_number; - u32 directory_id; - - u32 dummy1; - u32 dummy2; - u32 dummy3; -}; - -struct ncp_objectname_ioctl_32 -{ - s32 auth_type; - u32 object_name_len; - compat_caddr_t object_name; /* an userspace data, in most cases user name */ -}; - -struct ncp_privatedata_ioctl_32 -{ - u32 len; - compat_caddr_t data; /* ~1000 for NDS */ -}; - -#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32) -#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32) -#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32) -#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32) -#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32) - -static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_ioctl_request_32 n32; - struct ncp_ioctl_request __user *p = compat_alloc_user_space(sizeof(*p)); - - if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)) || - put_user(n32.function, &p->function) || - put_user(n32.size, &p->size) || - put_user(compat_ptr(n32.data), &p->data)) - return -EFAULT; - - return sys_ioctl(fd, NCP_IOC_NCPREQUEST, (unsigned long)p); -} - -static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - __kernel_uid_t kuid; - int err; - - cmd = NCP_IOC_GETMOUNTUID2; - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&kuid); - set_fs(old_fs); - - if (!err) - err = put_user(kuid, - (unsigned int __user *) compat_ptr(arg)); - - return err; -} - -static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - struct ncp_fs_info_v2_32 n32; - struct ncp_fs_info_v2 n; - int err; - - if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32))) - return -EFAULT; - if (n32.version != NCP_GET_FS_INFO_VERSION_V2) - return -EINVAL; - n.version = NCP_GET_FS_INFO_VERSION_V2; - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n); - set_fs(old_fs); - - if (!err) { - n32.version = n.version; - n32.mounted_uid = n.mounted_uid; - n32.connection = n.connection; - n32.buffer_size = n.buffer_size; - n32.volume_number = n.volume_number; - n32.directory_id = n.directory_id; - n32.dummy1 = n.dummy1; - n32.dummy2 = n.dummy2; - n32.dummy3 = n.dummy3; - err = copy_to_user(compat_ptr(arg), &n32, sizeof(n32)) ? -EFAULT : 0; - } - return err; -} - -static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg); - struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p)); - s32 auth_type; - u32 name_len; - int err; - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.object_name_len, &p->object_name_len) || - put_user(compat_ptr(n32.object_name), &p->object_name)) - return -EFAULT; - - err = sys_ioctl(fd, NCP_IOC_GETOBJECTNAME, (unsigned long)p); - if (err) - return err; - - if (get_user(auth_type, &p->auth_type) || - put_user(auth_type, &p32->auth_type) || - get_user(name_len, &p->object_name_len) || - put_user(name_len, &p32->object_name_len)) - return -EFAULT; - - return 0; -} - -static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg); - struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p)); - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.auth_type, &p->auth_type) || - put_user(n32.object_name_len, &p->object_name_len) || - put_user(compat_ptr(n32.object_name), &p->object_name)) - return -EFAULT; - - return sys_ioctl(fd, NCP_IOC_SETOBJECTNAME, (unsigned long)p); -} - -static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg); - struct ncp_privatedata_ioctl __user *p = - compat_alloc_user_space(sizeof(*p)); - u32 len; - int err; - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.len, &p->len) || - put_user(compat_ptr(n32.data), &p->data)) - return -EFAULT; - - err = sys_ioctl(fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)p); - if (err) - return err; - - if (get_user(len, &p->len) || - put_user(len, &p32->len)) - return -EFAULT; - - return 0; -} - -static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_privatedata_ioctl_32 n32; - struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg); - struct ncp_privatedata_ioctl __user *p = - compat_alloc_user_space(sizeof(*p)); - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.len, &p->len) || - put_user(compat_ptr(n32.data), &p->data)) - return -EFAULT; - - return sys_ioctl(fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)p); -} -#endif - static int lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { @@ -2777,6 +2430,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc) HANDLE_IOCTL(SIOCRTMSG, ret_einval) HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) #endif +#ifdef CONFIG_BLOCK HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo) HANDLE_IOCTL(BLKRAGET, w_long) HANDLE_IOCTL(BLKGETSIZE, w_long) @@ -2802,16 +2456,17 @@ HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans) HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) HANDLE_IOCTL(SG_IO,sg_ioctl_trans) HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) +#endif HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) +#ifdef CONFIG_BLOCK HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans) HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans) -HANDLE_IOCTL(LOOP_SET_STATUS, loop_status) -HANDLE_IOCTL(LOOP_GET_STATUS, loop_status) +#endif #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) #ifdef CONFIG_VT @@ -2821,19 +2476,6 @@ HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) #endif -HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) -HANDLE_IOCTL(EXT3_IOC32_GETVERSION, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_SETVERSION, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_GETRSVSZ, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_SETRSVSZ, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_GROUP_EXTEND, do_ext3_ioctl) -COMPATIBLE_IOCTL(EXT3_IOC_GROUP_ADD) -#ifdef CONFIG_JBD_DEBUG -HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl) -#endif /* One SMB ioctl needs translations. */ #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) @@ -2863,16 +2505,14 @@ HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) /* block stuff */ +#ifdef CONFIG_BLOCK HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget) HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset) HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) -/* vfat */ -HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32) -HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32) -HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32) /* Raw devices */ HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) +#endif /* Serial */ HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl) HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) @@ -2920,16 +2560,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) -#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) -HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) -HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) -HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) -HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) -HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) -HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) -HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) -#endif - /* dvb */ HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 816e8ef6456..8a3b6a1a6ad 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -139,7 +139,7 @@ static int init_dir(struct inode * inode) inode->i_fop = &configfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); return 0; } @@ -169,7 +169,7 @@ static int create_dir(struct config_item * k, struct dentry * p, if (!error) { error = configfs_create(d, mode, init_dir); if (!error) { - p->d_inode->i_nlink++; + inc_nlink(p->d_inode); (d)->d_op = &configfs_dentry_ops; } else { struct configfs_dirent *sd = d->d_fsdata; diff --git a/fs/configfs/file.c b/fs/configfs/file.c index 85105e50f7d..e6d5754a715 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c @@ -137,8 +137,8 @@ configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *pp if ((retval = fill_read_buffer(file->f_dentry,buffer))) goto out; } - pr_debug("%s: count = %d, ppos = %lld, buf = %s\n", - __FUNCTION__,count,*ppos,buffer->page); + pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", + __FUNCTION__, count, *ppos, buffer->page); retval = flush_read_buffer(buffer,buf,count,ppos); out: up(&buffer->sem); diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 3e5fe843e1d..68bd5c93ca5 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c @@ -84,7 +84,7 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_op = &configfs_dir_inode_operations; inode->i_fop = &configfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); } else { pr_debug("configfs: could not get root inode\n"); return -ENOMEM; diff --git a/fs/dcache.c b/fs/dcache.c index 17b392a2049..fc2faa44f8d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -32,6 +32,7 @@ #include <linux/seqlock.h> #include <linux/swap.h> #include <linux/bootmem.h> +#include "internal.h" int sysctl_vfs_cache_pressure __read_mostly = 100; @@ -1877,9 +1878,6 @@ kmem_cache_t *filp_cachep __read_mostly; EXPORT_SYMBOL(d_genocide); -extern void bdev_cache_init(void); -extern void chrdev_init(void); - void __init vfs_caches_init_early(void) { dcache_init_early(); diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 269e649e6dc..ecf3da9edf2 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -54,7 +54,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; } } @@ -87,7 +87,7 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; res = debugfs_mknod(dir, dentry, mode, 0); if (!res) - dir->i_nlink++; + inc_nlink(dir); return res; } diff --git a/fs/dnotify.c b/fs/dnotify.c index f932591df5a..2b0442db67e 100644 --- a/fs/dnotify.c +++ b/fs/dnotify.c @@ -92,7 +92,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) prev = &odn->dn_next; } - error = f_setown(filp, current->pid, 0); + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); if (error) goto out_free; diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 8d544334bcd..557d5b614fa 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -720,9 +720,10 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile, /* Allocates an inode from the eventpoll file system */ inode = ep_eventpoll_inode(); - error = PTR_ERR(inode); - if (IS_ERR(inode)) + if (IS_ERR(inode)) { + error = PTR_ERR(inode); goto eexit_2; + } /* Allocates a free descriptor to plug the file onto */ error = get_unused_fd(); diff --git a/fs/exec.c b/fs/exec.c index a8efe35176b..d993ea1a81a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -46,7 +46,7 @@ #include <linux/security.h> #include <linux/syscalls.h> #include <linux/rmap.h> -#include <linux/acct.h> +#include <linux/tsacct_kern.h> #include <linux/cn_proc.h> #include <linux/audit.h> @@ -58,7 +58,7 @@ #endif int core_uses_pid; -char core_pattern[65] = "core"; +char core_pattern[128] = "core"; int suid_dumpable = 0; EXPORT_SYMBOL(suid_dumpable); @@ -1318,7 +1318,7 @@ static void format_corename(char *corename, const char *pattern, long signr) case 'h': down_read(&uts_sem); rc = snprintf(out_ptr, out_end - out_ptr, - "%s", system_utsname.nodename); + "%s", utsname()->nodename); up_read(&uts_sem); if (rc > out_end - out_ptr) goto out; @@ -1463,6 +1463,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) int retval = 0; int fsuid = current->fsuid; int flag = 0; + int ispipe = 0; binfmt = current->binfmt; if (!binfmt || !binfmt->core_dump) @@ -1504,22 +1505,34 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) lock_kernel(); format_corename(corename, core_pattern, signr); unlock_kernel(); - file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600); + if (corename[0] == '|') { + /* SIGPIPE can happen, but it's just never processed */ + if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { + printk(KERN_INFO "Core dump to %s pipe failed\n", + corename); + goto fail_unlock; + } + ispipe = 1; + } else + file = filp_open(corename, + O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); if (IS_ERR(file)) goto fail_unlock; inode = file->f_dentry->d_inode; if (inode->i_nlink > 1) goto close_fail; /* multiple links - don't dump */ - if (d_unhashed(file->f_dentry)) + if (!ispipe && d_unhashed(file->f_dentry)) goto close_fail; - if (!S_ISREG(inode->i_mode)) + /* AK: actually i see no reason to not allow this for named pipes etc., + but keep the previous behaviour for now. */ + if (!ispipe && !S_ISREG(inode->i_mode)) goto close_fail; if (!file->f_op) goto close_fail; if (!file->f_op->write) goto close_fail; - if (do_truncate(file->f_dentry, 0, 0, file) != 0) + if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0) goto close_fail; retval = binfmt->core_dump(signr, regs, file); diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 4c39009350f..93e77c3d249 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -315,7 +315,7 @@ struct getdents_callback { * the name matching the specified inode number. */ static int filldir_one(void * __buf, const char * name, int len, - loff_t pos, ino_t ino, unsigned int d_type) + loff_t pos, u64 ino, unsigned int d_type) { struct getdents_callback *buf = __buf; int result = 0; diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 92ea8265d7d..3e7a84a1e50 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -661,5 +661,8 @@ const struct file_operations ext2_dir_operations = { .read = generic_read_dir, .readdir = ext2_readdir, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .fsync = ext2_sync_file, }; diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index e65a019fc7a..c19ac153f56 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -137,6 +137,7 @@ extern void ext2_set_inode_flags(struct inode *inode); /* ioctl.c */ extern int ext2_ioctl (struct inode *, struct file *, unsigned int, unsigned long); +extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); /* namei.c */ struct dentry *ext2_get_parent(struct dentry *child); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 23e2c7ccec1..2dba473c524 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -41,17 +41,18 @@ static int ext2_release_file (struct inode * inode, struct file * filp) */ const struct file_operations ext2_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .mmap = generic_file_mmap, .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, - .readv = generic_file_readv, - .writev = generic_file_writev, .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, @@ -63,6 +64,9 @@ const struct file_operations ext2_xip_file_operations = { .read = xip_file_read, .write = xip_file_write, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .mmap = xip_file_mmap, .open = generic_file_open, .release = ext2_release_file, diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 3ca9afdf713..1dfba77eab1 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -11,6 +11,8 @@ #include <linux/capability.h> #include <linux/time.h> #include <linux/sched.h> +#include <linux/compat.h> +#include <linux/smp_lock.h> #include <asm/current.h> #include <asm/uaccess.h> @@ -80,3 +82,33 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, return -ENOTTY; } } + +#ifdef CONFIG_COMPAT +long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + /* These are just misnamed, they actually get/put from/to user an int */ + switch (cmd) { + case EXT2_IOC32_GETFLAGS: + cmd = EXT2_IOC_GETFLAGS; + break; + case EXT2_IOC32_SETFLAGS: + cmd = EXT2_IOC_SETFLAGS; + break; + case EXT2_IOC32_GETVERSION: + cmd = EXT2_IOC_GETVERSION; + break; + case EXT2_IOC32_SETVERSION: + cmd = EXT2_IOC_SETVERSION; + break; + default: + return -ENOIOCTLCMD; + } + lock_kernel(); + ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); + unlock_kernel(); + return ret; +} +#endif diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 4ca82498532..e1af5b4cf80 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -326,7 +326,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, ext2_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 429acbb4e06..d0b54f30b91 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c @@ -44,6 +44,9 @@ const struct file_operations ext3_dir_operations = { .read = generic_read_dir, .readdir = ext3_readdir, /* we take BKL. needed?*/ .ioctl = ext3_ioctl, /* BKL held */ +#ifdef CONFIG_COMPAT + .compat_ioctl = ext3_compat_ioctl, +#endif .fsync = ext3_sync_file, /* BKL held */ #ifdef CONFIG_EXT3_INDEX .release = ext3_release_dir, diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 994efd189f4..e96c388047e 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -48,14 +48,15 @@ static int ext3_release_file (struct inode * inode, struct file * filp) } static ssize_t -ext3_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +ext3_file_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_dentry->d_inode; ssize_t ret; int err; - ret = generic_file_aio_write(iocb, buf, count, pos); + ret = generic_file_aio_write(iocb, iov, nr_segs, pos); /* * Skip flushing if there was an error, or if nothing was written. @@ -111,9 +112,10 @@ const struct file_operations ext3_file_operations = { .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = ext3_file_write, - .readv = generic_file_readv, - .writev = generic_file_writev, .ioctl = ext3_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext3_compat_ioctl, +#endif .mmap = generic_file_mmap, .open = generic_file_open, .release = ext3_release_file, diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index dcf4f1dd108..03ba5bcab18 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -36,6 +36,7 @@ #include <linux/writeback.h> #include <linux/mpage.h> #include <linux/uio.h> +#include <linux/bio.h> #include "xattr.h" #include "acl.h" @@ -1073,7 +1074,7 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode, return bh; if (buffer_uptodate(bh)) return bh; - ll_rw_block(READ, 1, &bh); + ll_rw_block(READ_META, 1, &bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) return bh; @@ -2540,7 +2541,7 @@ make_io: */ get_bh(bh); bh->b_end_io = end_buffer_read_sync; - submit_bh(READ, bh); + submit_bh(READ_META, bh); wait_on_buffer(bh); if (!buffer_uptodate(bh)) { ext3_error(inode->i_sb, "ext3_get_inode_loc", diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 3a6b012d120..12daa686957 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c @@ -13,9 +13,10 @@ #include <linux/ext3_fs.h> #include <linux/ext3_jbd.h> #include <linux/time.h> +#include <linux/compat.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> - int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg) { @@ -252,3 +253,55 @@ flags_err: return -ENOTTY; } } + +#ifdef CONFIG_COMPAT +long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + /* These are just misnamed, they actually get/put from/to user an int */ + switch (cmd) { + case EXT3_IOC32_GETFLAGS: + cmd = EXT3_IOC_GETFLAGS; + break; + case EXT3_IOC32_SETFLAGS: + cmd = EXT3_IOC_SETFLAGS; + break; + case EXT3_IOC32_GETVERSION: + cmd = EXT3_IOC_GETVERSION; + break; + case EXT3_IOC32_SETVERSION: + cmd = EXT3_IOC_SETVERSION; + break; + case EXT3_IOC32_GROUP_EXTEND: + cmd = EXT3_IOC_GROUP_EXTEND; + break; + case EXT3_IOC32_GETVERSION_OLD: + cmd = EXT3_IOC_GETVERSION_OLD; + break; + case EXT3_IOC32_SETVERSION_OLD: + cmd = EXT3_IOC_SETVERSION_OLD; + break; +#ifdef CONFIG_JBD_DEBUG + case EXT3_IOC32_WAIT_FOR_READONLY: + cmd = EXT3_IOC_WAIT_FOR_READONLY; + break; +#endif + case EXT3_IOC32_GETRSVSZ: + cmd = EXT3_IOC_GETRSVSZ; + break; + case EXT3_IOC32_SETRSVSZ: + cmd = EXT3_IOC_SETRSVSZ; + break; + case EXT3_IOC_GROUP_ADD: + break; + default: + return -ENOIOCTLCMD; + } + lock_kernel(); + ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); + unlock_kernel(); + return ret; +} +#endif diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 85d132c37ee..906731a20f1 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -35,6 +35,7 @@ #include <linux/string.h> #include <linux/quotaops.h> #include <linux/buffer_head.h> +#include <linux/bio.h> #include <linux/smp_lock.h> #include "namei.h" @@ -870,7 +871,7 @@ restart: bh = ext3_getblk(NULL, dir, b++, 0, &err); bh_use[ra_max] = bh; if (bh) - ll_rw_block(READ, 1, &bh); + ll_rw_block(READ_META, 1, &bh); } } if ((bh = bh_use[ra_ptr++]) == NULL) @@ -1615,12 +1616,12 @@ static int ext3_delete_entry (handle_t *handle, */ static inline void ext3_inc_count(handle_t *handle, struct inode *inode) { - inode->i_nlink++; + inc_nlink(inode); } static inline void ext3_dec_count(handle_t *handle, struct inode *inode) { - inode->i_nlink--; + drop_nlink(inode); } static int ext3_add_nondir(handle_t *handle, @@ -1742,7 +1743,7 @@ retry: inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; dir_block = ext3_bread (handle, inode, 0, 1, &err); if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ + drop_nlink(inode); /* is this nlink == 0? */ ext3_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -1774,7 +1775,7 @@ retry: iput (inode); goto out_stop; } - dir->i_nlink++; + inc_nlink(dir); ext3_update_dx_flag(dir); ext3_mark_inode_dirty(handle, dir); d_instantiate(dentry, inode); @@ -2044,7 +2045,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) "empty directory has nlink!=2 (%d)", inode->i_nlink); inode->i_version++; - inode->i_nlink = 0; + clear_nlink(inode); /* There's no need to set i_disksize: the fact that i_nlink is * zero will ensure that the right thing happens during any * recovery. */ @@ -2052,7 +2053,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) ext3_orphan_add(handle, inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; ext3_mark_inode_dirty(handle, inode); - dir->i_nlink--; + drop_nlink(dir); ext3_update_dx_flag(dir); ext3_mark_inode_dirty(handle, dir); @@ -2103,7 +2104,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; ext3_update_dx_flag(dir); ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; + drop_nlink(inode); if (!inode->i_nlink) ext3_orphan_add(handle, inode); inode->i_ctime = dir->i_ctime; @@ -2325,7 +2326,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, } if (new_inode) { - new_inode->i_nlink--; + drop_nlink(new_inode); new_inode->i_ctime = CURRENT_TIME_SEC; } old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; @@ -2336,11 +2337,11 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); ext3_journal_dirty_metadata(handle, dir_bh); - old_dir->i_nlink--; + drop_nlink(old_dir); if (new_inode) { - new_inode->i_nlink--; + drop_nlink(new_inode); } else { - new_dir->i_nlink++; + inc_nlink(new_dir); ext3_update_dx_flag(new_dir); ext3_mark_inode_dirty(handle, new_dir); } diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 698b85bb1dd..69c439f4438 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -20,6 +20,7 @@ #include <linux/dirent.h> #include <linux/smp_lock.h> #include <linux/buffer_head.h> +#include <linux/compat.h> #include <asm/uaccess.h> static inline loff_t fat_make_i_pos(struct super_block *sb, @@ -647,7 +648,7 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) } static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct fat_ioctl_filldir_callback *buf = __buf; struct dirent __user *d1 = buf->dirent; @@ -741,10 +742,65 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, return ret; } +#ifdef CONFIG_COMPAT +#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) +#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) + +static long fat_compat_put_dirent32(struct dirent *d, + struct compat_dirent __user *d32) +{ + if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) + return -EFAULT; + + __put_user(d->d_ino, &d32->d_ino); + __put_user(d->d_off, &d32->d_off); + __put_user(d->d_reclen, &d32->d_reclen); + if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) + return -EFAULT; + + return 0; +} + +static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, + unsigned long arg) +{ + struct compat_dirent __user *p = compat_ptr(arg); + int ret; + mm_segment_t oldfs = get_fs(); + struct dirent d[2]; + + switch (cmd) { + case VFAT_IOCTL_READDIR_BOTH32: + cmd = VFAT_IOCTL_READDIR_BOTH; + break; + case VFAT_IOCTL_READDIR_SHORT32: + cmd = VFAT_IOCTL_READDIR_SHORT; + break; + default: + return -ENOIOCTLCMD; + } + + set_fs(KERNEL_DS); + lock_kernel(); + ret = fat_dir_ioctl(file->f_dentry->d_inode, file, + cmd, (unsigned long) &d); + unlock_kernel(); + set_fs(oldfs); + if (ret >= 0) { + ret |= fat_compat_put_dirent32(&d[0], p); + ret |= fat_compat_put_dirent32(&d[1], p + 1); + } + return ret; +} +#endif /* CONFIG_COMPAT */ + const struct file_operations fat_dir_operations = { .read = generic_read_dir, .readdir = fat_readdir, .ioctl = fat_dir_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = fat_compat_dir_ioctl, +#endif .fsync = file_fsync, }; diff --git a/fs/fat/file.c b/fs/fat/file.c index d50fc47169c..f4b8f8b3fbd 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -127,8 +127,6 @@ const struct file_operations fat_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, - .readv = generic_file_readv, - .writev = generic_file_writev, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, diff --git a/fs/fcntl.c b/fs/fcntl.c index d35cbc6bc11..e4f26165f12 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -250,19 +250,22 @@ static int setfl(int fd, struct file * filp, unsigned long arg) return error; } -static void f_modown(struct file *filp, unsigned long pid, +static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, uid_t uid, uid_t euid, int force) { write_lock_irq(&filp->f_owner.lock); if (force || !filp->f_owner.pid) { - filp->f_owner.pid = pid; + put_pid(filp->f_owner.pid); + filp->f_owner.pid = get_pid(pid); + filp->f_owner.pid_type = type; filp->f_owner.uid = uid; filp->f_owner.euid = euid; } write_unlock_irq(&filp->f_owner.lock); } -int f_setown(struct file *filp, unsigned long arg, int force) +int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, + int force) { int err; @@ -270,15 +273,44 @@ int f_setown(struct file *filp, unsigned long arg, int force) if (err) return err; - f_modown(filp, arg, current->uid, current->euid, force); + f_modown(filp, pid, type, current->uid, current->euid, force); return 0; } +EXPORT_SYMBOL(__f_setown); +int f_setown(struct file *filp, unsigned long arg, int force) +{ + enum pid_type type; + struct pid *pid; + int who = arg; + int result; + type = PIDTYPE_PID; + if (who < 0) { + type = PIDTYPE_PGID; + who = -who; + } + rcu_read_lock(); + pid = find_pid(who); + result = __f_setown(filp, pid, type, force); + rcu_read_unlock(); + return result; +} EXPORT_SYMBOL(f_setown); void f_delown(struct file *filp) { - f_modown(filp, 0, 0, 0, 1); + f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1); +} + +pid_t f_getown(struct file *filp) +{ + pid_t pid; + read_lock(&filp->f_owner.lock); + pid = pid_nr(filp->f_owner.pid); + if (filp->f_owner.pid_type == PIDTYPE_PGID) + pid = -pid; + read_unlock(&filp->f_owner.lock); + return pid; } static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, @@ -319,7 +351,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, * current syscall conventions, the only way * to fix this will be in libc. */ - err = filp->f_owner.pid; + err = f_getown(filp); force_successful_syscall_return(); break; case F_SETOWN: @@ -470,24 +502,19 @@ static void send_sigio_to_task(struct task_struct *p, void send_sigio(struct fown_struct *fown, int fd, int band) { struct task_struct *p; - int pid; + enum pid_type type; + struct pid *pid; read_lock(&fown->lock); + type = fown->pid_type; pid = fown->pid; if (!pid) goto out_unlock_fown; read_lock(&tasklist_lock); - if (pid > 0) { - p = find_task_by_pid(pid); - if (p) { - send_sigio_to_task(p, fown, fd, band); - } - } else { - do_each_task_pid(-pid, PIDTYPE_PGID, p) { - send_sigio_to_task(p, fown, fd, band); - } while_each_task_pid(-pid, PIDTYPE_PGID, p); - } + do_each_pid_task(pid, type, p) { + send_sigio_to_task(p, fown, fd, band); + } while_each_pid_task(pid, type, p); read_unlock(&tasklist_lock); out_unlock_fown: read_unlock(&fown->lock); @@ -503,9 +530,12 @@ static void send_sigurg_to_task(struct task_struct *p, int send_sigurg(struct fown_struct *fown) { struct task_struct *p; - int pid, ret = 0; + enum pid_type type; + struct pid *pid; + int ret = 0; read_lock(&fown->lock); + type = fown->pid_type; pid = fown->pid; if (!pid) goto out_unlock_fown; @@ -513,16 +543,9 @@ int send_sigurg(struct fown_struct *fown) ret = 1; read_lock(&tasklist_lock); - if (pid > 0) { - p = find_task_by_pid(pid); - if (p) { - send_sigurg_to_task(p, fown); - } - } else { - do_each_task_pid(-pid, PIDTYPE_PGID, p) { - send_sigurg_to_task(p, fown); - } while_each_task_pid(-pid, PIDTYPE_PGID, p); - } + do_each_pid_task(pid, type, p) { + send_sigurg_to_task(p, fown); + } while_each_pid_task(pid, type, p); read_unlock(&tasklist_lock); out_unlock_fown: read_unlock(&fown->lock); diff --git a/fs/file_table.c b/fs/file_table.c index bc35a40417d..24f25a057d9 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -174,6 +174,7 @@ void fastcall __fput(struct file *file) fops_put(file->f_op); if (file->f_mode & FMODE_WRITE) put_write_access(inode); + put_pid(file->f_owner.pid); file_kill(file); file->f_dentry = NULL; file->f_vfsmnt = NULL; diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 892643dc9af..c403b66ec83 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -22,8 +22,7 @@ #include <linux/blkdev.h> #include <linux/backing-dev.h> #include <linux/buffer_head.h> - -extern struct super_block *blockdev_superblock; +#include "internal.h" /** * __mark_inode_dirty - internal function @@ -320,7 +319,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (!bdi_cap_writeback_dirty(bdi)) { list_move(&inode->i_list, &sb->s_dirty); - if (sb == blockdev_superblock) { + if (sb_is_blkdev_sb(sb)) { /* * Dirty memory-backed blockdev: the ramdisk * driver does this. Skip just this inode @@ -337,14 +336,14 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; - if (sb != blockdev_superblock) + if (!sb_is_blkdev_sb(sb)) break; /* Skip a congested fs */ list_move(&inode->i_list, &sb->s_dirty); continue; /* Skip a congested blockdev */ } if (wbc->bdi && bdi != wbc->bdi) { - if (sb != blockdev_superblock) + if (!sb_is_blkdev_sb(sb)) break; /* fs has the wrong queue */ list_move(&inode->i_list, &sb->s_dirty); continue; /* blockdev has wrong queue */ diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 79ec1f23d4d..16b39c053d4 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -116,7 +116,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) return 0; parent = fuse_control_sb->s_root; - parent->d_inode->i_nlink++; + inc_nlink(parent->d_inode); sprintf(name, "%llu", (unsigned long long) fc->id); parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2, &simple_dir_inode_operations, diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 4fc557c40cc..66571eafbb1 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -680,14 +680,15 @@ static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, * request_end(). Otherwise add it to the processing list, and set * the 'sent' flag. */ -static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, - unsigned long nr_segs, loff_t *off) +static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { int err; struct fuse_req *req; struct fuse_in *in; struct fuse_copy_state cs; unsigned reqsize; + struct file *file = iocb->ki_filp; struct fuse_conn *fc = fuse_get_conn(file); if (!fc) return -EPERM; @@ -761,15 +762,6 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, return err; } -static ssize_t fuse_dev_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *off) -{ - struct iovec iov; - iov.iov_len = nbytes; - iov.iov_base = buf; - return fuse_dev_readv(file, &iov, 1, off); -} - /* Look up request on processing list by unique ID */ static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) { @@ -814,15 +806,15 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, * it from the list and copy the rest of the buffer to the request. * The request is finished by calling request_end() */ -static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, - unsigned long nr_segs, loff_t *off) +static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { int err; unsigned nbytes = iov_length(iov, nr_segs); struct fuse_req *req; struct fuse_out_header oh; struct fuse_copy_state cs; - struct fuse_conn *fc = fuse_get_conn(file); + struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); if (!fc) return -EPERM; @@ -898,15 +890,6 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, return err; } -static ssize_t fuse_dev_write(struct file *file, const char __user *buf, - size_t nbytes, loff_t *off) -{ - struct iovec iov; - iov.iov_len = nbytes; - iov.iov_base = (char __user *) buf; - return fuse_dev_writev(file, &iov, 1, off); -} - static unsigned fuse_dev_poll(struct file *file, poll_table *wait) { unsigned mask = POLLOUT | POLLWRNORM; @@ -1041,10 +1024,10 @@ static int fuse_dev_fasync(int fd, struct file *file, int on) const struct file_operations fuse_dev_operations = { .owner = THIS_MODULE, .llseek = no_llseek, - .read = fuse_dev_read, - .readv = fuse_dev_readv, - .write = fuse_dev_write, - .writev = fuse_dev_writev, + .read = do_sync_read, + .aio_read = fuse_dev_read, + .write = do_sync_write, + .aio_write = fuse_dev_write, .poll = fuse_dev_poll, .release = fuse_dev_release, .fasync = fuse_dev_fasync, diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index f85b2a282f1..8605155db17 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -508,7 +508,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) /* Set nlink to zero so the inode can be cleared, if the inode does have more links this will be discovered at the next lookup/getattr */ - inode->i_nlink = 0; + clear_nlink(inode); fuse_invalidate_attr(inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); @@ -534,7 +534,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) err = req->out.h.error; fuse_put_request(fc, req); if (!err) { - entry->d_inode->i_nlink = 0; + clear_nlink(entry->d_inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); } else if (err == -EINTR) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 5c4fcd1dbf5..183626868ee 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -753,8 +753,10 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) static const struct file_operations fuse_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = fuse_file_mmap, .open = fuse_open, .flush = fuse_flush, diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 7cd8cc03aea..37d681b4f21 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -246,7 +246,7 @@ static int hfs_unlink(struct inode *dir, struct dentry *dentry) if (res) return res; - inode->i_nlink--; + drop_nlink(inode); hfs_delete_inode(inode); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); @@ -273,7 +273,7 @@ static int hfs_rmdir(struct inode *dir, struct dentry *dentry) res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); if (res) return res; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; hfs_delete_inode(inode); mark_inode_dirty(inode); diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index d05641c35fc..02f5573e034 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -601,8 +601,10 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) static const struct file_operations hfs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, .fsync = file_fsync, diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 1f9ece0de32..7e309751645 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -298,7 +298,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, if (res) return res; - inode->i_nlink++; + inc_nlink(inode); hfsplus_instantiate(dst_dentry, inode, cnid); atomic_inc(&inode->i_count); inode->i_ctime = CURRENT_TIME_SEC; @@ -338,7 +338,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) return res; if (inode->i_nlink > 0) - inode->i_nlink--; + drop_nlink(inode); hfsplus_delete_inode(inode); if (inode->i_ino != cnid && !inode->i_nlink) { if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { @@ -348,7 +348,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) } else inode->i_flags |= S_DEAD; } else - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); @@ -387,7 +387,7 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) res = hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); if (res) return res; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; hfsplus_delete_inode(inode); mark_inode_dirty(inode); diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 8a1ca5ef7ad..3915635b447 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -246,12 +246,8 @@ struct hfsplus_readdir_data { /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support * chattr/lsattr */ -#define HFSPLUS_IOC_EXT2_GETFLAGS _IOR('f', 1, long) -#define HFSPLUS_IOC_EXT2_SETFLAGS _IOW('f', 2, long) - -#define EXT2_FLAG_IMMUTABLE 0x00000010 /* Immutable file */ -#define EXT2_FLAG_APPEND 0x00000020 /* writes to file may only append */ -#define EXT2_FLAG_NODUMP 0x00000040 /* do not dump file */ +#define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS +#define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS /* diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 0eb1a609266..9e367524963 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -282,8 +282,10 @@ static struct inode_operations hfsplus_file_inode_operations = { static const struct file_operations hfsplus_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, .fsync = file_fsync, diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 13cf848ac83..79fd10402ea 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -28,11 +28,11 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case HFSPLUS_IOC_EXT2_GETFLAGS: flags = 0; if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE) - flags |= EXT2_FLAG_IMMUTABLE; /* EXT2_IMMUTABLE_FL */ + flags |= FS_IMMUTABLE_FL; /* EXT2_IMMUTABLE_FL */ if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND) - flags |= EXT2_FLAG_APPEND; /* EXT2_APPEND_FL */ + flags |= FS_APPEND_FL; /* EXT2_APPEND_FL */ if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP) - flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */ + flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */ return put_user(flags, (int __user *)arg); case HFSPLUS_IOC_EXT2_SETFLAGS: { if (IS_RDONLY(inode)) @@ -44,32 +44,31 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, if (get_user(flags, (int __user *)arg)) return -EFAULT; - if (flags & (EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND) || + if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { if (!capable(CAP_LINUX_IMMUTABLE)) return -EPERM; } /* don't silently ignore unsupported ext2 flags */ - if (flags & ~(EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND| - EXT2_FLAG_NODUMP)) + if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) return -EOPNOTSUPP; - if (flags & EXT2_FLAG_IMMUTABLE) { /* EXT2_IMMUTABLE_FL */ + if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */ inode->i_flags |= S_IMMUTABLE; HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; } else { inode->i_flags &= ~S_IMMUTABLE; HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE; } - if (flags & EXT2_FLAG_APPEND) { /* EXT2_APPEND_FL */ + if (flags & FS_APPEND_FL) { /* EXT2_APPEND_FL */ inode->i_flags |= S_APPEND; HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND; } else { inode->i_flags &= ~S_APPEND; HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND; } - if (flags & EXT2_FLAG_NODUMP) /* EXT2_NODUMP_FL */ + if (flags & FS_NODUMP_FL) /* EXT2_NODUMP_FL */ HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP; else HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP; diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 322e876c35e..b6bd33ca373 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -385,13 +385,11 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) static const struct file_operations hostfs_file_fops = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, .sendfile = generic_file_sendfile, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, - .readv = generic_file_readv, - .writev = generic_file_writev, - .write = generic_file_write, + .write = do_sync_write, .mmap = generic_file_mmap, .open = hostfs_file_open, .release = NULL, diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index d9eb19b7b8a..8b94d24855f 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -113,7 +113,7 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, { ssize_t retval; - retval = generic_file_write(file, buf, count, ppos); + retval = do_sync_write(file, buf, count, ppos); if (retval > 0) hpfs_i(file->f_dentry->d_inode)->i_dirty = 1; return retval; @@ -122,8 +122,10 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, const struct file_operations hpfs_file_ops = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .write = hpfs_file_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .release = hpfs_file_release, .fsync = hpfs_file_fsync, diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 59e7dc182a0..2507e7393f3 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -89,7 +89,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) brelse(bh); hpfs_mark_4buffers_dirty(&qbh0); hpfs_brelse4(&qbh0); - dir->i_nlink++; + inc_nlink(dir); insert_inode_hash(result); if (result->i_uid != current->fsuid || @@ -434,7 +434,7 @@ again: unlock_kernel(); return -ENOSPC; default: - inode->i_nlink--; + drop_nlink(inode); err = 0; } goto out; @@ -494,8 +494,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) err = -ENOSPC; break; default: - dir->i_nlink--; - inode->i_nlink = 0; + drop_nlink(dir); + clear_nlink(inode); err = 0; } goto out; @@ -590,7 +590,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, int r; if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) { if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, (char *)new_name, new_len, NULL, &qbh1))) { - new_inode->i_nlink = 0; + clear_nlink(new_inode); copy_de(nde, &de); memcpy(nde->name, new_name, new_len); hpfs_mark_4buffers_dirty(&qbh1); @@ -635,8 +635,8 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, end: hpfs_i(i)->i_parent_dir = new_dir->i_ino; if (S_ISDIR(i->i_mode)) { - new_dir->i_nlink++; - old_dir->i_nlink--; + inc_nlink(new_dir); + drop_nlink(old_dir); } if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { fnode->up = new_dir->i_ino; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index f5b8f329aca..5e03b2f67b9 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -377,7 +377,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; @@ -418,7 +418,7 @@ static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) - dir->i_nlink++; + inc_nlink(dir); return retval; } diff --git a/fs/inode.c b/fs/inode.c index abf77471e6c..bf6bec4e54f 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -362,27 +362,6 @@ int invalidate_inodes(struct super_block * sb) } EXPORT_SYMBOL(invalidate_inodes); - -int __invalidate_device(struct block_device *bdev) -{ - struct super_block *sb = get_super(bdev); - int res = 0; - - if (sb) { - /* - * no need to lock the super, get_super holds the - * read mutex so the filesystem cannot go away - * under us (->put_super runs with the write lock - * hold). - */ - shrink_dcache_sb(sb); - res = invalidate_inodes(sb); - drop_super(sb); - } - invalidate_bdev(bdev, 0); - return res; -} -EXPORT_SYMBOL(__invalidate_device); static int can_unuse(struct inode *inode) { @@ -678,7 +657,7 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he return inode; } -static inline unsigned long hash(struct super_block *sb, unsigned long hashval) +static unsigned long hash(struct super_block *sb, unsigned long hashval) { unsigned long tmp; @@ -1024,7 +1003,7 @@ void generic_delete_inode(struct inode *inode) list_del_init(&inode->i_list); list_del_init(&inode->i_sb_list); - inode->i_state|=I_FREEING; + inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; spin_unlock(&inode_lock); @@ -1231,13 +1210,15 @@ void file_update_time(struct file *file) return; now = current_fs_time(inode->i_sb); - if (!timespec_equal(&inode->i_mtime, &now)) + if (!timespec_equal(&inode->i_mtime, &now)) { + inode->i_mtime = now; sync_it = 1; - inode->i_mtime = now; + } - if (!timespec_equal(&inode->i_ctime, &now)) + if (!timespec_equal(&inode->i_ctime, &now)) { + inode->i_ctime = now; sync_it = 1; - inode->i_ctime = now; + } if (sync_it) mark_inode_dirty_sync(inode); diff --git a/fs/internal.h b/fs/internal.h new file mode 100644 index 00000000000..ea00126c9a5 --- /dev/null +++ b/fs/internal.h @@ -0,0 +1,55 @@ +/* fs/ internal definitions + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/ioctl32.h> + +struct super_block; + +/* + * block_dev.c + */ +#ifdef CONFIG_BLOCK +extern struct super_block *blockdev_superblock; +extern void __init bdev_cache_init(void); + +static inline int sb_is_blkdev_sb(struct super_block *sb) +{ + return sb == blockdev_superblock; +} + +#else +static inline void bdev_cache_init(void) +{ +} + +static inline int sb_is_blkdev_sb(struct super_block *sb) +{ + return 0; +} +#endif + +/* + * char_dev.c + */ +extern void __init chrdev_init(void); + +/* + * compat_ioctl.c + */ +#ifdef CONFIG_COMPAT +extern struct ioctl_trans ioctl_start[]; +extern int ioctl_table_size; +#endif + +/* + * namespace.c + */ +extern int copy_mount_options(const void __user *, unsigned long *); diff --git a/fs/ioprio.c b/fs/ioprio.c index 78b1deae3fa..6dc6721d9e8 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -1,7 +1,7 @@ /* * fs/ioprio.c * - * Copyright (C) 2004 Jens Axboe <axboe@suse.de> + * Copyright (C) 2004 Jens Axboe <axboe@kernel.dk> * * Helper functions for setting/querying io priorities of processes. The * system calls closely mimmick getpriority/setpriority, see the man page for @@ -47,8 +47,8 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) /* see wmb() in current_io_context() */ smp_read_barrier_depends(); - if (ioc && ioc->set_ioprio) - ioc->set_ioprio(ioc, ioprio); + if (ioc) + ioc->ioprio_changed = 1; task_unlock(task); return 0; @@ -81,7 +81,12 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) } ret = -ESRCH; - read_lock_irq(&tasklist_lock); + /* + * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic", + * so we can't use rcu_read_lock(). See re-copy of ->ioprio + * in copy_process(). + */ + read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: if (!who) @@ -124,7 +129,7 @@ free_uid: ret = -EINVAL; } - read_unlock_irq(&tasklist_lock); + read_unlock(&tasklist_lock); return ret; } @@ -170,7 +175,7 @@ asmlinkage long sys_ioprio_get(int which, int who) int ret = -ESRCH; int tmpio; - read_lock_irq(&tasklist_lock); + read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: if (!who) @@ -221,7 +226,7 @@ asmlinkage long sys_ioprio_get(int which, int who) ret = -EINVAL; } - read_unlock_irq(&tasklist_lock); + read_unlock(&tasklist_lock); return ret; } diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index f5cf9c93e24..3f7899ea4cb 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -1052,9 +1052,8 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type) dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); - inode->i_nlink--; inode->i_ctime = dir->i_ctime; - mark_inode_dirty(inode); + inode_dec_link_count(inode); d_delete(dentry); /* This also frees the inode */ @@ -1632,8 +1631,10 @@ static const struct file_operations jffs_file_operations = { .open = generic_file_open, .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .ioctl = jffs_ioctl, .mmap = generic_file_readonly_mmap, .fsync = jffs_fsync, diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index edd8371fc6a..9def6adf4a5 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -588,7 +588,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) } dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); - dir_i->i_nlink++; + inc_nlink(dir_i); jffs2_free_raw_dirent(rd); @@ -615,7 +615,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) } ret = jffs2_unlink(dir_i, dentry); if (!ret) - dir_i->i_nlink--; + drop_nlink(dir_i); return ret; } @@ -823,7 +823,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, if (victim_f) { /* There was a victim. Kill it off nicely */ - new_dentry->d_inode->i_nlink--; + drop_nlink(new_dentry->d_inode); /* Don't oops if the victim was a dirent pointing to an inode which didn't exist. */ if (victim_f->inocache) { @@ -836,7 +836,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, /* If it was a directory we moved, and there was no victim, increase i_nlink on its new parent */ if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) - new_dir_i->i_nlink++; + inc_nlink(new_dir_i); /* Unlink the original */ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), @@ -848,7 +848,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, /* Oh shit. We really ought to make a single node which can do both atomically */ struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); down(&f->sem); - old_dentry->d_inode->i_nlink++; + inc_nlink(old_dentry->d_inode); if (f->inocache) f->inocache->nlink++; up(&f->sem); @@ -862,7 +862,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, } if (S_ISDIR(old_dentry->d_inode->i_mode)) - old_dir_i->i_nlink--; + drop_nlink(old_dir_i); new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 3ed6e3e120b..242875f77cb 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -42,8 +42,10 @@ const struct file_operations jffs2_file_operations = { .llseek = generic_file_llseek, .open = generic_file_open, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .ioctl = jffs2_ioctl, .mmap = generic_file_readonly_mmap, .fsync = jffs2_fsync, diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 72d9909d95f..7bc1a4201c0 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -277,13 +277,13 @@ void jffs2_read_inode (struct inode *inode) for (fd=f->dents; fd; fd = fd->next) { if (fd->type == DT_DIR && fd->ino) - inode->i_nlink++; + inc_nlink(inode); } /* and '..' */ - inode->i_nlink++; + inc_nlink(inode); /* Root dir gets i_nlink 3 for some reason */ if (inode->i_ino == 1) - inode->i_nlink++; + inc_nlink(inode); inode->i_op = &jffs2_dir_inode_operations; inode->i_fop = &jffs2_dir_operations; diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index e2281300979..4d84bdc8829 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -5,16 +5,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -183,7 +183,7 @@ cleanup: posix_acl_release(acl); } else inode->i_mode &= ~current->fs->umask; - + JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | inode->i_mode; diff --git a/fs/jfs/endian24.h b/fs/jfs/endian24.h index ab7cd0567c9..79494c4f2b1 100644 --- a/fs/jfs/endian24.h +++ b/fs/jfs/endian24.h @@ -1,5 +1,5 @@ /* - * Copyright (c) International Business Machines Corp., 2001 + * Copyright (C) International Business Machines Corp., 2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 1c9745be5ad..34181b8f5a0 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -103,14 +103,12 @@ struct inode_operations jfs_file_inode_operations = { const struct file_operations jfs_file_operations = { .open = jfs_open, .llseek = generic_file_llseek, - .write = generic_file_write, - .read = generic_file_read, + .write = do_sync_write, + .read = do_sync_read, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, - .readv = generic_file_readv, - .writev = generic_file_writev, - .sendfile = generic_file_sendfile, + .sendfile = generic_file_sendfile, .fsync = jfs_fsync, .release = jfs_release, .ioctl = jfs_ioctl, diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index a223cf4faa9..f5719117edf 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -33,7 +33,7 @@ void jfs_read_inode(struct inode *inode) { - if (diRead(inode)) { + if (diRead(inode)) { make_bad_inode(inode); return; } @@ -227,7 +227,7 @@ int jfs_get_block(struct inode *ip, sector_t lblock, #ifdef _JFS_4K if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) goto unlock; - rc = extAlloc(ip, xlen, lblock64, &xad, FALSE); + rc = extAlloc(ip, xlen, lblock64, &xad, false); if (rc) goto unlock; diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index 67b3774820e..37db5248826 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c @@ -6,7 +6,6 @@ */ #include <linux/fs.h> -#include <linux/ext2_fs.h> #include <linux/ctype.h> #include <linux/capability.h> #include <linux/time.h> @@ -22,13 +21,13 @@ static struct { long jfs_flag; long ext2_flag; } jfs_map[] = { - {JFS_NOATIME_FL, EXT2_NOATIME_FL}, - {JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL}, - {JFS_SYNC_FL, EXT2_SYNC_FL}, - {JFS_SECRM_FL, EXT2_SECRM_FL}, - {JFS_UNRM_FL, EXT2_UNRM_FL}, - {JFS_APPEND_FL, EXT2_APPEND_FL}, - {JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL}, + {JFS_NOATIME_FL, FS_NOATIME_FL}, + {JFS_DIRSYNC_FL, FS_DIRSYNC_FL}, + {JFS_SYNC_FL, FS_SYNC_FL}, + {JFS_SECRM_FL, FS_SECRM_FL}, + {JFS_UNRM_FL, FS_UNRM_FL}, + {JFS_APPEND_FL, FS_APPEND_FL}, + {JFS_IMMUTABLE_FL, FS_IMMUTABLE_FL}, {0, 0}, }; diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index a76293767c7..455fa429204 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (C) International Business Machines Corp., 2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_ACL diff --git a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h index 7f3e9ac454f..79c61805bd3 100644 --- a/fs/jfs/jfs_btree.h +++ b/fs/jfs/jfs_btree.h @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_BTREE diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index 81f0e514c49..9c5d59632aa 100644 --- a/fs/jfs/jfs_debug.c +++ b/fs/jfs/jfs_debug.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h index 9f2572aea56..40b20111383 100644 --- a/fs/jfs/jfs_dinode.h +++ b/fs/jfs/jfs_dinode.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2001 + * Copyright (C) International Business Machines Corp., 2000-2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_DINODE diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index c161c98954e..23546c8fd48 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -30,28 +30,28 @@ * * the working state of the block allocation map is accessed in * two directions: - * + * * 1) allocation and free requests that start at the dmap * level and move up through the dmap control pages (i.e. * the vast majority of requests). - * - * 2) allocation requests that start at dmap control page + * + * 2) allocation requests that start at dmap control page * level and work down towards the dmaps. - * - * the serialization scheme used here is as follows. * - * requests which start at the bottom are serialized against each - * other through buffers and each requests holds onto its buffers - * as it works it way up from a single dmap to the required level + * the serialization scheme used here is as follows. + * + * requests which start at the bottom are serialized against each + * other through buffers and each requests holds onto its buffers + * as it works it way up from a single dmap to the required level * of dmap control page. * requests that start at the top are serialized against each other * and request that start from the bottom by the multiple read/single * write inode lock of the bmap inode. requests starting at the top * take this lock in write mode while request starting at the bottom * take the lock in read mode. a single top-down request may proceed - * exclusively while multiple bottoms-up requests may proceed - * simultaneously (under the protection of busy buffers). - * + * exclusively while multiple bottoms-up requests may proceed + * simultaneously (under the protection of busy buffers). + * * in addition to information found in dmaps and dmap control pages, * the working state of the block allocation map also includes read/ * write information maintained in the bmap descriptor (i.e. total @@ -59,7 +59,7 @@ * a single exclusive lock (BMAP_LOCK) is used to guard this information * in the face of multiple-bottoms up requests. * (lock ordering: IREAD_LOCK, BMAP_LOCK); - * + * * accesses to the persistent state of the block allocation map (limited * to the persistent bitmaps in dmaps) is guarded by (busy) buffers. */ @@ -120,7 +120,7 @@ static int dbGetL2AGSize(s64 nblocks); /* * buddy table * - * table used for determining buddy sizes within characters of + * table used for determining buddy sizes within characters of * dmap bitmap words. the characters themselves serve as indexes * into the table, with the table elements yielding the maximum * binary buddy of free bits within the character. @@ -146,7 +146,7 @@ static const s8 budtab[256] = { /* - * NAME: dbMount() + * NAME: dbMount() * * FUNCTION: initializate the block allocation map. * @@ -223,12 +223,12 @@ int dbMount(struct inode *ipbmap) /* - * NAME: dbUnmount() + * NAME: dbUnmount() * * FUNCTION: terminate the block allocation map in preparation for * file system unmount. * - * the in-core bmap descriptor is written to disk and + * the in-core bmap descriptor is written to disk and * the memory for this descriptor is freed. * * PARAMETERS: @@ -311,7 +311,7 @@ int dbSync(struct inode *ipbmap) /* - * NAME: dbFree() + * NAME: dbFree() * * FUNCTION: free the specified block range from the working block * allocation map. @@ -397,14 +397,14 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) * * FUNCTION: update the allocation state (free or allocate) of the * specified block range in the persistent block allocation map. - * + * * the blocks will be updated in the persistent map one * dmap at a time. * * PARAMETERS: * ipbmap - pointer to in-core inode for the block map. - * free - TRUE if block range is to be freed from the persistent - * map; FALSE if it is to be allocated. + * free - 'true' if block range is to be freed from the persistent + * map; 'false' if it is to be allocated. * blkno - starting block number of the range. * nblocks - number of contiguous blocks in the range. * tblk - transaction block; @@ -475,7 +475,7 @@ dbUpdatePMap(struct inode *ipbmap, /* update the bits of the dmap words. the first and last * words may only have a subset of their bits updated. if * this is the case, we'll work against that word (i.e. - * partial first and/or last) only in a single pass. a + * partial first and/or last) only in a single pass. a * single pass will also be used to update all words that * are to have all their bits updated. */ @@ -662,11 +662,11 @@ unlock: * the block allocation policy uses hints and a multi-step * approach. * - * for allocation requests smaller than the number of blocks + * for allocation requests smaller than the number of blocks * per dmap, we first try to allocate the new blocks * immediately following the hint. if these blocks are not * available, we try to allocate blocks near the hint. if - * no blocks near the hint are available, we next try to + * no blocks near the hint are available, we next try to * allocate within the same dmap as contains the hint. * * if no blocks are available in the dmap or the allocation @@ -713,7 +713,7 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) #endif /* _STILL_TO_PORT */ /* get the log2 number of blocks to be allocated. - * if the number of blocks is not a log2 multiple, + * if the number of blocks is not a log2 multiple, * it will be rounded up to the next log2 multiple. */ l2nb = BLKSTOL2(nblocks); @@ -906,7 +906,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) * validate extent request: * * note: defragfs policy: - * max 64 blocks will be moved. + * max 64 blocks will be moved. * allocation request size must be satisfied from a single dmap. */ if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) { @@ -1333,7 +1333,7 @@ dbAllocNear(struct bmap * bmp, * or two sub-trees, depending on the allocation group size. * we search the top nodes of these subtrees left to right for * sufficient free space. if sufficient free space is found, - * the subtree is searched to find the leftmost leaf that + * the subtree is searched to find the leftmost leaf that * has free space. once we have made it to the leaf, we * move the search to the next lower level dmap control page * corresponding to this leaf. we continue down the dmap control @@ -1398,7 +1398,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) * that fully describes the allocation group since the allocation * group is already fully described by a dmap. in this case, we * just call dbAllocCtl() to search the dmap tree and allocate the - * required space if available. + * required space if available. * * if the allocation group is completely free, dbAllocCtl() is * also called to allocate the required space. this is done for @@ -1450,7 +1450,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth; ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1)); - /* dmap control page trees fan-out by 4 and a single allocation + /* dmap control page trees fan-out by 4 and a single allocation * group may be described by 1 or 2 subtrees within the ag level * dmap control page, depending upon the ag size. examine the ag's * subtrees for sufficient free space, starting with the leftmost @@ -1633,7 +1633,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) /* starting at the specified dmap control page level and block * number, search down the dmap control levels for the starting - * block number of a dmap page that contains or starts off + * block number of a dmap page that contains or starts off * sufficient free blocks. */ for (lev = level, b = *blkno; lev >= 0; lev--) { @@ -1677,7 +1677,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) } /* adjust the block number to reflect the location within - * the dmap control page (i.e. the leaf) at which free + * the dmap control page (i.e. the leaf) at which free * space was found. */ b += (((s64) leafidx) << budmin); @@ -1700,12 +1700,12 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) * NAME: dbAllocCtl() * * FUNCTION: attempt to allocate a specified number of contiguous - * blocks starting within a specific dmap. - * + * blocks starting within a specific dmap. + * * this routine is called by higher level routines that search * the dmap control pages above the actual dmaps for contiguous * free space. the result of successful searches by these - * routines are the starting block numbers within dmaps, with + * routines are the starting block numbers within dmaps, with * the dmaps themselves containing the desired contiguous free * space or starting a contiguous free space of desired size * that is made up of the blocks of one or more dmaps. these @@ -1872,14 +1872,14 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) * * FUNCTION: attempt to allocate a specified number of contiguous blocks * from a specified dmap. - * + * * this routine checks if the contiguous blocks are available. * if so, nblocks of blocks are allocated; otherwise, ENOSPC is * returned. * * PARAMETERS: * mp - pointer to bmap descriptor - * dp - pointer to dmap to attempt to allocate blocks from. + * dp - pointer to dmap to attempt to allocate blocks from. * l2nb - log2 number of contiguous block desired. * nblocks - actual number of contiguous block desired. * results - on successful return, set to the starting block number @@ -1890,7 +1890,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) * -ENOSPC - insufficient disk resources * -EIO - i/o error * - * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or + * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or * IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit; */ static int @@ -2032,7 +2032,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, /* root changed. bubble the change up to the dmap control pages. * if the adjustment of the upper level control pages fails, - * backout the deallocation. + * backout the deallocation. */ if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) { word = (blkno & (BPERDMAP - 1)) >> L2DBWORD; @@ -2245,7 +2245,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * words (i.e. partial first and/or last) on an individual basis * (a single pass), freeing the bits of interest by hand and updating * the leaf corresponding to the dmap word. a single pass will be used - * for all dmap words fully contained within the specified range. + * for all dmap words fully contained within the specified range. * within this pass, the bits of all fully contained dmap words will * be marked as free in a single shot and the leaves will be updated. a * single leaf may describe the free space of multiple dmap words, @@ -2267,7 +2267,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, */ if (nb < DBWORD) { /* free (zero) the appropriate bits within this - * dmap word. + * dmap word. */ dp->wmap[word] &= cpu_to_le32(~(ONES << (DBWORD - nb) @@ -2327,7 +2327,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, BMAP_LOCK(bmp); - /* update the free count for the allocation group and + /* update the free count for the allocation group and * map. */ agno = blkno >> bmp->db_agl2size; @@ -2378,7 +2378,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * or deallocation resulted in the root change. this range * is respresented by a single leaf of the current dmapctl * and the leaf will be updated with this value, possibly - * causing a binary buddy system within the leaves to be + * causing a binary buddy system within the leaves to be * split or joined. the update may also cause the dmapctl's * dmtree to be updated. * @@ -2394,7 +2394,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * requires the dmap control page to be adjusted. * newval - the new value of the lower level dmap or dmap control * page root. - * alloc - TRUE if adjustment is due to an allocation. + * alloc - 'true' if adjustment is due to an allocation. * level - current level of dmap control page (i.e. L0, L1, L2) to * be adjusted. * @@ -2590,7 +2590,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) } } - /* adjust the dmap tree to reflect the specified leaf's new + /* adjust the dmap tree to reflect the specified leaf's new * value. */ dbAdjTree(tp, leafno, newval); @@ -2638,7 +2638,7 @@ static int dbBackSplit(dmtree_t * tp, int leafno) /* the back split is accomplished by iteratively finding the leaf * that starts the buddy system that contains the specified leaf and * splitting that system in two. this iteration continues until - * the specified leaf becomes the start of a buddy system. + * the specified leaf becomes the start of a buddy system. * * determine maximum possible l2 size for the specified leaf. */ @@ -2853,7 +2853,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) * NAME: dbFindLeaf() * * FUNCTION: search a dmtree_t for sufficient free blocks, returning - * the index of a leaf describing the free blocks if + * the index of a leaf describing the free blocks if * sufficient free blocks are found. * * the search starts at the top of the dmtree_t tree and @@ -2869,7 +2869,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) * * RETURN VALUES: * 0 - success - * -ENOSPC - insufficient free blocks. + * -ENOSPC - insufficient free blocks. */ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) { @@ -3090,7 +3090,7 @@ static int blkstol2(s64 nb) /* - * NAME: dbAllocBottomUp() + * NAME: dbAllocBottomUp() * * FUNCTION: alloc the specified block range from the working block * allocation map. @@ -3241,7 +3241,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno, BMAP_LOCK(bmp); /* if this allocation group is completely free, - * update the highest active allocation group number + * update the highest active allocation group number * if this allocation group is the new max. */ agno = blkno >> bmp->db_agl2size; @@ -3273,7 +3273,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno, * NAME: dbExtendFS() * * FUNCTION: extend bmap from blkno for nblocks; - * dbExtendFS() updates bmap ready for dbAllocBottomUp(); + * dbExtendFS() updates bmap ready for dbAllocBottomUp(); * * L2 * | @@ -3284,13 +3284,13 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno, * d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm; * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm * - * <---old---><----------------------------extend-----------------------> + * <---old---><----------------------------extend-----------------------> */ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) { struct jfs_sb_info *sbi = JFS_SBI(ipbmap->i_sb); int nbperpage = sbi->nbperpage; - int i, i0 = TRUE, j, j0 = TRUE, k, n; + int i, i0 = true, j, j0 = true, k, n; s64 newsize; s64 p; struct metapage *mp, *l2mp, *l1mp = NULL, *l0mp = NULL; @@ -3330,7 +3330,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0; /* - * reconfigure db_agfree[] + * reconfigure db_agfree[] * from old AG configuration to new AG configuration; * * coalesce contiguous k (newAGSize/oldAGSize) AGs; @@ -3398,7 +3398,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE; l1leaf = l1dcp->stree + CTLLEAFIND + j; p = BLKTOL0(blkno, sbi->l2nbperpage); - j0 = FALSE; + j0 = false; } else { /* assign/init L1 page */ l1mp = get_metapage(ipbmap, p, PSIZE, 0); @@ -3432,7 +3432,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) l0leaf = l0dcp->stree + CTLLEAFIND + i; p = BLKTODMAP(blkno, sbi->l2nbperpage); - i0 = FALSE; + i0 = false; } else { /* assign/init L0 page */ l0mp = get_metapage(ipbmap, p, PSIZE, 0); @@ -3491,7 +3491,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) } /* for each dmap in a L0 */ /* - * build current L0 page from its leaves, and + * build current L0 page from its leaves, and * initialize corresponding parent L1 leaf */ *l1leaf = dbInitDmapCtl(l0dcp, 0, ++i); @@ -3515,7 +3515,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) } /* for each L0 in a L1 */ /* - * build current L1 page from its leaves, and + * build current L1 page from its leaves, and * initialize corresponding parent L2 leaf */ *l2leaf = dbInitDmapCtl(l1dcp, 1, ++j); @@ -3570,7 +3570,7 @@ void dbFinalizeBmap(struct inode *ipbmap) * finalize bmap control page */ //finalize: - /* + /* * compute db_agpref: preferred ag to allocate from * (the leftmost ag with average free space in it); */ @@ -3614,9 +3614,9 @@ void dbFinalizeBmap(struct inode *ipbmap) /* * compute db_aglevel, db_agheigth, db_width, db_agstart: - * an ag is covered in aglevel dmapctl summary tree, - * at agheight level height (from leaf) with agwidth number of nodes - * each, which starts at agstart index node of the smmary tree node + * an ag is covered in aglevel dmapctl summary tree, + * at agheight level height (from leaf) with agwidth number of nodes + * each, which starts at agstart index node of the smmary tree node * array; */ bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize); @@ -3635,13 +3635,13 @@ void dbFinalizeBmap(struct inode *ipbmap) /* * NAME: dbInitDmap()/ujfs_idmap_page() - * + * * FUNCTION: initialize working/persistent bitmap of the dmap page * for the specified number of blocks: - * + * * at entry, the bitmaps had been initialized as free (ZEROS); - * The number of blocks will only account for the actually - * existing blocks. Blocks which don't actually exist in + * The number of blocks will only account for the actually + * existing blocks. Blocks which don't actually exist in * the aggregate will be marked as allocated (ONES); * * PARAMETERS: @@ -3677,7 +3677,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks) /* * free the bits corresponding to the block range (ZEROS): - * note: not all bits of the first and last words may be contained + * note: not all bits of the first and last words may be contained * within the block range. */ for (r = nblocks; r > 0; r -= nb, blkno += nb) { @@ -3709,7 +3709,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks) } /* - * mark bits following the range to be freed (non-existing + * mark bits following the range to be freed (non-existing * blocks) as allocated (ONES) */ @@ -3741,11 +3741,11 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks) /* * NAME: dbInitDmapTree()/ujfs_complete_dmap() - * + * * FUNCTION: initialize summary tree of the specified dmap: * * at entry, bitmap of the dmap has been initialized; - * + * * PARAMETERS: * dp - dmap to complete * blkno - starting block number for this dmap @@ -3769,7 +3769,7 @@ static int dbInitDmapTree(struct dmap * dp) /* init each leaf from corresponding wmap word: * note: leaf is set to NOFREE(-1) if all blocks of corresponding - * bitmap word are allocated. + * bitmap word are allocated. */ cp = tp->stree + le32_to_cpu(tp->leafidx); for (i = 0; i < LPERDMAP; i++) @@ -3782,10 +3782,10 @@ static int dbInitDmapTree(struct dmap * dp) /* * NAME: dbInitTree()/ujfs_adjtree() - * + * * FUNCTION: initialize binary buddy summary tree of a dmap or dmapctl. * - * at entry, the leaves of the tree has been initialized + * at entry, the leaves of the tree has been initialized * from corresponding bitmap word or root of summary tree * of the child control page; * configure binary buddy system at the leaf level, then @@ -3813,15 +3813,15 @@ static int dbInitTree(struct dmaptree * dtp) /* * configure the leaf levevl into binary buddy system * - * Try to combine buddies starting with a buddy size of 1 - * (i.e. two leaves). At a buddy size of 1 two buddy leaves - * can be combined if both buddies have a maximum free of l2min; - * the combination will result in the left-most buddy leaf having - * a maximum free of l2min+1. - * After processing all buddies for a given size, process buddies - * at the next higher buddy size (i.e. current size * 2) and - * the next maximum free (current free + 1). - * This continues until the maximum possible buddy combination + * Try to combine buddies starting with a buddy size of 1 + * (i.e. two leaves). At a buddy size of 1 two buddy leaves + * can be combined if both buddies have a maximum free of l2min; + * the combination will result in the left-most buddy leaf having + * a maximum free of l2min+1. + * After processing all buddies for a given size, process buddies + * at the next higher buddy size (i.e. current size * 2) and + * the next maximum free (current free + 1). + * This continues until the maximum possible buddy combination * yields maximum free. */ for (l2free = dtp->budmin, bsize = 1; l2free < l2max; @@ -3845,10 +3845,10 @@ static int dbInitTree(struct dmaptree * dtp) * bubble summary information of leaves up the tree. * * Starting at the leaf node level, the four nodes described by - * the higher level parent node are compared for a maximum free and - * this maximum becomes the value of the parent node. - * when all lower level nodes are processed in this fashion then - * move up to the next level (parent becomes a lower level node) and + * the higher level parent node are compared for a maximum free and + * this maximum becomes the value of the parent node. + * when all lower level nodes are processed in this fashion then + * move up to the next level (parent becomes a lower level node) and * continue the process for that level. */ for (child = le32_to_cpu(dtp->leafidx), @@ -3857,7 +3857,7 @@ static int dbInitTree(struct dmaptree * dtp) /* get index of 1st node of parent level */ parent = (child - 1) >> 2; - /* set the value of the parent node as the maximum + /* set the value of the parent node as the maximum * of the four nodes of the current level. */ for (i = 0, cp = tp + child, cp1 = tp + parent; @@ -3885,8 +3885,8 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i) dcp->budmin = L2BPERDMAP + L2LPERCTL * level; /* - * initialize the leaves of current level that were not covered - * by the specified input block range (i.e. the leaves have no + * initialize the leaves of current level that were not covered + * by the specified input block range (i.e. the leaves have no * low level dmapctl or dmap). */ cp = &dcp->stree[CTLLEAFIND + i]; @@ -3900,9 +3900,9 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i) /* * NAME: dbGetL2AGSize()/ujfs_getagl2size() - * + * * FUNCTION: Determine log2(allocation group size) from aggregate size - * + * * PARAMETERS: * nblocks - Number of blocks in aggregate * @@ -3935,8 +3935,8 @@ static int dbGetL2AGSize(s64 nblocks) /* * NAME: dbMapFileSizeToMapSize() - * - * FUNCTION: compute number of blocks the block allocation map file + * + * FUNCTION: compute number of blocks the block allocation map file * can cover from the map file size; * * RETURNS: Number of blocks which can be covered by this block map file; @@ -3968,7 +3968,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap) npages = nblocks >> JFS_SBI(sb)->l2nbperpage; level = BMAPPGTOLEV(npages); - /* At each level, accumulate the number of dmap pages covered by + /* At each level, accumulate the number of dmap pages covered by * the number of full child levels below it; * repeat for the last incomplete child level. */ @@ -3990,7 +3990,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap) npages--; } - /* convert the number of dmaps into the number of blocks + /* convert the number of dmaps into the number of blocks * which can be covered by the dmaps; */ nblocks = ndmaps << L2BPERDMAP; diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h index 8b14cc8e022..45ea454c74b 100644 --- a/fs/jfs/jfs_dmap.h +++ b/fs/jfs/jfs_dmap.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_DMAP @@ -27,7 +27,7 @@ #define L2LPERDMAP 8 /* l2 number of leaves per dmap tree */ #define DBWORD 32 /* # of blks covered by a map word */ #define L2DBWORD 5 /* l2 # of blks covered by a mword */ -#define BUDMIN L2DBWORD /* max free string in a map word */ +#define BUDMIN L2DBWORD /* max free string in a map word */ #define BPERDMAP (LPERDMAP * DBWORD) /* num of blks per dmap */ #define L2BPERDMAP 13 /* l2 num of blks per dmap */ #define CTLTREESIZE (1024+256+64+16+4+1) /* size of a dmapctl tree */ @@ -57,7 +57,7 @@ #define MAXMAPSIZE MAXL2SIZE /* maximum aggregate map size */ -/* +/* * determine the maximum free string for four (lower level) nodes * of the tree. */ @@ -122,7 +122,7 @@ static __inline signed char TREEMAX(signed char *cp) #define BLKTOCTL(b,s,l) \ (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s))) -/* +/* * convert aggregate map size to the zero origin dmapctl level of the * top dmapctl. */ @@ -192,13 +192,13 @@ typedef union dmtree { /* macros for accessing fields within dmtree */ #define dmt_nleafs t1.nleafs -#define dmt_l2nleafs t1.l2nleafs -#define dmt_leafidx t1.leafidx -#define dmt_height t1.height -#define dmt_budmin t1.budmin -#define dmt_stree t1.stree +#define dmt_l2nleafs t1.l2nleafs +#define dmt_leafidx t1.leafidx +#define dmt_height t1.height +#define dmt_budmin t1.budmin +#define dmt_stree t1.stree -/* +/* * on-disk aggregate disk allocation map descriptor. */ struct dbmap_disk { @@ -237,7 +237,7 @@ struct dbmap { s64 dn_agsize; /* num of blks per alloc group */ signed char dn_maxfreebud; /* max free buddy system */ }; /* - 4096 - */ -/* +/* * in-memory aggregate disk allocation map descriptor. */ struct bmap { diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 6c3f0831984..ecb2216d881 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -78,7 +78,7 @@ * * case-insensitive search: * - * fold search key; + * fold search key; * * case-insensitive search of B-tree: * for internal entry, router key is already folded; @@ -93,7 +93,7 @@ * else * return no match; * - * serialization: + * serialization: * target directory inode lock is being held on entry/exit * of all main directory service routines. * @@ -925,7 +925,7 @@ int dtInsert(tid_t tid, struct inode *ip, * * return: 0 - success; * errno - failure; - * leaf page unpinned; + * leaf page unpinned; */ static int dtSplitUp(tid_t tid, struct inode *ip, struct dtsplit * split, struct btstack * btstack) @@ -3767,7 +3767,7 @@ static int ciCompare(struct component_name * key, /* search key */ * across page boundary * * return: non-zero on error - * + * */ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, int ri, struct component_name * key, int flag) @@ -3780,13 +3780,13 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_KERNEL); if (lkey.name == NULL) - return -ENOSPC; + return -ENOMEM; rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_KERNEL); if (rkey.name == NULL) { kfree(lkey.name); - return -ENOSPC; + return -ENOMEM; } /* get left and right key */ diff --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h index 13e4fdf0772..af8513f7864 100644 --- a/fs/jfs/jfs_dtree.h +++ b/fs/jfs/jfs_dtree.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_DTREE @@ -80,7 +80,7 @@ struct idtentry { /* * leaf node entry head/only segment * - * For legacy filesystems, name contains 13 wchars -- no index field + * For legacy filesystems, name contains 13 wchars -- no index field */ struct ldtentry { __le32 inumber; /* 4: 4-byte aligned */ diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 4c74f0944f7..a35bdca6a80 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -74,7 +74,7 @@ static s64 extRoundDown(s64 nb); * extent that is used as an allocation hint if the * xaddr of the xad is non-zero. on successful exit, * the xad describes the newly allocated extent. - * abnr - boolean_t indicating whether the newly allocated extent + * abnr - bool indicating whether the newly allocated extent * should be marked as allocated but not recorded. * * RETURN VALUES: @@ -83,7 +83,7 @@ static s64 extRoundDown(s64 nb); * -ENOSPC - insufficient disk resources. */ int -extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) +extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) { struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); s64 nxlen, nxaddr, xoff, hint, xaddr = 0; @@ -117,7 +117,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) * following the hint extent. */ if (offsetXAD(xp) + nxlen == xoff && - abnr == ((xp->flag & XAD_NOTRECORDED) ? TRUE : FALSE)) + abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false)) xaddr = hint + nxlen; /* adjust the hint to the last block of the extent */ @@ -125,7 +125,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) } /* allocate the disk blocks for the extent. initially, extBalloc() - * will try to allocate disk blocks for the requested size (xlen). + * will try to allocate disk blocks for the requested size (xlen). * if this fails (xlen contiguous free blocks not avaliable), it'll * try to allocate a smaller number of blocks (producing a smaller * extent), with this smaller number of blocks consisting of the @@ -148,9 +148,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) } /* determine the value of the extent flag */ - xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0; + xflag = abnr ? XAD_NOTRECORDED : 0; - /* if we can extend the hint extent to cover the current request, + /* if we can extend the hint extent to cover the current request, * extend it. otherwise, insert a new extent to * cover the current request. */ @@ -159,7 +159,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) else rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0); - /* if the extend or insert failed, + /* if the extend or insert failed, * free the newly allocated blocks and return the error. */ if (rc) { @@ -203,7 +203,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) * xlen - request size of the resulting extent. * xp - pointer to an xad. on successful exit, the xad * describes the newly allocated extent. - * abnr - boolean_t indicating whether the newly allocated extent + * abnr - bool indicating whether the newly allocated extent * should be marked as allocated but not recorded. * * RETURN VALUES: @@ -211,7 +211,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) * -EIO - i/o error. * -ENOSPC - insufficient disk resources. */ -int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) +int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) { struct super_block *sb = ip->i_sb; s64 xaddr, xlen, nxaddr, delta, xoff; @@ -235,7 +235,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) xoff = offsetXAD(xp); /* if the extend page is abnr and if the request is for - * the extent to be allocated and recorded, + * the extent to be allocated and recorded, * make the page allocated and recorded. */ if ((xp->flag & XAD_NOTRECORDED) && !abnr) { @@ -397,7 +397,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) if ((rc = xtLookupList(ip, &lxdl, &xadl, 0))) return (rc); - /* check if not extent exists for the previous page. + /* check if not extent exists for the previous page. * this is possible for sparse files. */ if (xadl.nxad == 0) { @@ -410,7 +410,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) */ xp->flag &= XAD_NOTRECORDED; - if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { + if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { jfs_error(ip->i_sb, "extHint: corrupt xtree"); return -EIO; } @@ -476,7 +476,7 @@ int extFill(struct inode *ip, xad_t * xp) XADaddress(xp, 0); /* allocate an extent to fill the hole */ - if ((rc = extAlloc(ip, nbperpage, blkno, xp, FALSE))) + if ((rc = extAlloc(ip, nbperpage, blkno, xp, false))) return (rc); assert(lengthPXD(xp) == nbperpage); @@ -492,7 +492,7 @@ int extFill(struct inode *ip, xad_t * xp) * FUNCTION: allocate disk blocks to form an extent. * * initially, we will try to allocate disk blocks for the - * requested size (nblocks). if this fails (nblocks + * requested size (nblocks). if this fails (nblocks * contiguous free blocks not avaliable), we'll try to allocate * a smaller number of blocks (producing a smaller extent), with * this smaller number of blocks consisting of the requested @@ -500,7 +500,7 @@ int extFill(struct inode *ip, xad_t * xp) * number (i.e. 16 -> 8). we'll continue to round down and * retry the allocation until the number of blocks to allocate * is smaller than the number of blocks per page. - * + * * PARAMETERS: * ip - the inode of the file. * hint - disk block number to be used as an allocation hint. @@ -509,7 +509,7 @@ int extFill(struct inode *ip, xad_t * xp) * exit, this value is set to the number of blocks actually * allocated. * blkno - pointer to a block address that is filled in on successful - * return with the starting block number of the newly + * return with the starting block number of the newly * allocated block range. * * RETURN VALUES: @@ -530,7 +530,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) /* get the number of blocks to initially attempt to allocate. * we'll first try the number of blocks requested unless this * number is greater than the maximum number of contiguous free - * blocks in the map. in that case, we'll start off with the + * blocks in the map. in that case, we'll start off with the * maximum free. */ max = (s64) 1 << bmp->db_maxfreebud; @@ -582,19 +582,19 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) * * FUNCTION: attempt to extend an extent's allocation. * - * initially, we will try to extend the extent's allocation - * in place. if this fails, we'll try to move the extent - * to a new set of blocks. if moving the extent, we initially + * Initially, we will try to extend the extent's allocation + * in place. If this fails, we'll try to move the extent + * to a new set of blocks. If moving the extent, we initially * will try to allocate disk blocks for the requested size - * (nnew). if this fails (new contiguous free blocks not - * avaliable), we'll try to allocate a smaller number of + * (newnblks). if this fails (new contiguous free blocks not + * avaliable), we'll try to allocate a smaller number of * blocks (producing a smaller extent), with this smaller * number of blocks consisting of the requested number of * blocks rounded down to the next smaller power of 2 - * number (i.e. 16 -> 8). we'll continue to round down and + * number (i.e. 16 -> 8). We'll continue to round down and * retry the allocation until the number of blocks to allocate * is smaller than the number of blocks per page. - * + * * PARAMETERS: * ip - the inode of the file. * blkno - starting block number of the extents current allocation. @@ -625,7 +625,7 @@ extBrealloc(struct inode *ip, return (rc); } - /* in place extension not possible. + /* in place extension not possible. * try to move the extent to a new set of blocks. */ return (extBalloc(ip, blkno, newnblks, newblkno)); diff --git a/fs/jfs/jfs_extent.h b/fs/jfs/jfs_extent.h index e80fc7ced87..b567e12c52d 100644 --- a/fs/jfs/jfs_extent.h +++ b/fs/jfs/jfs_extent.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2001 + * Copyright (C) International Business Machines Corp., 2000-2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_EXTENT @@ -22,10 +22,10 @@ #define INOHINT(ip) \ (addressPXD(&(JFS_IP(ip)->ixpxd)) + lengthPXD(&(JFS_IP(ip)->ixpxd)) - 1) -extern int extAlloc(struct inode *, s64, s64, xad_t *, boolean_t); +extern int extAlloc(struct inode *, s64, s64, xad_t *, bool); extern int extFill(struct inode *, xad_t *); extern int extHint(struct inode *, s64, xad_t *); -extern int extRealloc(struct inode *, s64, xad_t *, boolean_t); +extern int extRealloc(struct inode *, s64, xad_t *, bool); extern int extRecord(struct inode *, xad_t *); #endif /* _H_JFS_EXTENT */ diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h index 72a5588faec..9901928668c 100644 --- a/fs/jfs/jfs_filsys.h +++ b/fs/jfs/jfs_filsys.h @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_FILSYS @@ -21,9 +21,9 @@ /* * jfs_filsys.h * - * file system (implementation-dependent) constants + * file system (implementation-dependent) constants * - * refer to <limits.h> for system wide implementation-dependent constants + * refer to <limits.h> for system wide implementation-dependent constants */ /* @@ -49,7 +49,7 @@ #define JFS_DFS 0x20000000 /* DCE DFS LFS support */ -#define JFS_LINUX 0x10000000 /* Linux support */ +#define JFS_LINUX 0x10000000 /* Linux support */ /* case-sensitive name/directory support */ /* directory option */ @@ -59,7 +59,7 @@ #define JFS_COMMIT 0x00000f00 /* commit option mask */ #define JFS_GROUPCOMMIT 0x00000100 /* group (of 1) commit */ #define JFS_LAZYCOMMIT 0x00000200 /* lazy commit */ -#define JFS_TMPFS 0x00000400 /* temporary file system - +#define JFS_TMPFS 0x00000400 /* temporary file system - * do not log/commit: */ @@ -196,7 +196,7 @@ * followed by 1st extent of map */ #define AITBL_OFF (AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1)) - /* + /* * 1st extent of aggregate inode table */ #define SUPER2_OFF (AITBL_OFF + INODE_EXTENT_SIZE) @@ -270,13 +270,13 @@ */ #define FM_CLEAN 0x00000000 /* file system is unmounted and clean */ #define FM_MOUNT 0x00000001 /* file system is mounted cleanly */ -#define FM_DIRTY 0x00000002 /* file system was not unmounted and clean - * when mounted or +#define FM_DIRTY 0x00000002 /* file system was not unmounted and clean + * when mounted or * commit failure occurred while being mounted: - * fsck() must be run to repair + * fsck() must be run to repair */ #define FM_LOGREDO 0x00000004 /* log based recovery (logredo()) failed: - * fsck() must be run to repair + * fsck() must be run to repair */ #define FM_EXTENDFS 0x00000008 /* file system extendfs() in progress */ diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 369d7f39c04..489a3d63002 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -78,8 +78,8 @@ static HLIST_HEAD(aggregate_hash); /* * forward references */ -static int diAllocAG(struct inomap *, int, boolean_t, struct inode *); -static int diAllocAny(struct inomap *, int, boolean_t, struct inode *); +static int diAllocAG(struct inomap *, int, bool, struct inode *); +static int diAllocAny(struct inomap *, int, bool, struct inode *); static int diAllocBit(struct inomap *, struct iag *, int); static int diAllocExt(struct inomap *, int, struct inode *); static int diAllocIno(struct inomap *, int, struct inode *); @@ -98,7 +98,7 @@ static void copy_to_dinode(struct dinode *, struct inode *); * FUNCTION: initialize the incore inode map control structures for * a fileset or aggregate init time. * - * the inode map's control structure (dinomap) is + * the inode map's control structure (dinomap) is * brought in from disk and placed in virtual memory. * * PARAMETERS: @@ -107,7 +107,7 @@ static void copy_to_dinode(struct dinode *, struct inode *); * RETURN VALUES: * 0 - success * -ENOMEM - insufficient free virtual memory. - * -EIO - i/o error. + * -EIO - i/o error. */ int diMount(struct inode *ipimap) { @@ -191,7 +191,7 @@ int diMount(struct inode *ipimap) * RETURN VALUES: * 0 - success * -ENOMEM - insufficient free virtual memory. - * -EIO - i/o error. + * -EIO - i/o error. */ int diUnmount(struct inode *ipimap, int mounterror) { @@ -281,7 +281,7 @@ int diSync(struct inode *ipimap) * on entry, the specifed incore inode should itself * specify the disk inode number corresponding to the * incore inode (i.e. i_number should be initialized). - * + * * this routine handles incore inode initialization for * both "special" and "regular" inodes. special inodes * are those required early in the mount process and @@ -289,7 +289,7 @@ int diSync(struct inode *ipimap) * is not yet initialized. these "special" inodes are * identified by a NULL inode map inode pointer and are * actually initialized by a call to diReadSpecial(). - * + * * for regular inodes, the iag describing the disk inode * is read from disk to determine the inode extent address * for the disk inode. with the inode extent address in @@ -302,9 +302,9 @@ int diSync(struct inode *ipimap) * * RETURN VALUES: * 0 - success - * -EIO - i/o error. + * -EIO - i/o error. * -ENOMEM - insufficient memory - * + * */ int diRead(struct inode *ip) { @@ -586,14 +586,14 @@ void diFreeSpecial(struct inode *ip) * page of the extent that contains the disk inode is * read and the disk inode portion of the incore inode * is copied to the disk inode. - * + * * PARAMETERS: * tid - transacation id * ip - pointer to incore inode to be written to the inode extent. * * RETURN VALUES: * 0 - success - * -EIO - i/o error. + * -EIO - i/o error. */ int diWrite(tid_t tid, struct inode *ip) { @@ -676,11 +676,11 @@ int diWrite(tid_t tid, struct inode *ip) * copy btree root from in-memory inode to on-disk inode * * (tlock is taken from inline B+-tree root in in-memory - * inode when the B+-tree root is updated, which is pointed + * inode when the B+-tree root is updated, which is pointed * by jfs_ip->blid as well as being on tx tlock list) * - * further processing of btree root is based on the copy - * in in-memory inode, where txLog() will log from, and, + * further processing of btree root is based on the copy + * in in-memory inode, where txLog() will log from, and, * for xtree root, txUpdateMap() will update map and reset * XAD_NEW bit; */ @@ -824,7 +824,7 @@ int diWrite(tid_t tid, struct inode *ip) memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd)); #endif /* _JFS_FASTDASD */ - /* release the buffer holding the updated on-disk inode. + /* release the buffer holding the updated on-disk inode. * the buffer will be later written by commit processing. */ write_metapage(mp); @@ -842,7 +842,7 @@ int diWrite(tid_t tid, struct inode *ip) * if the inode to be freed represents the first (only) * free inode within the iag, the iag will be placed on * the ag free inode list. - * + * * freeing the inode will cause the inode extent to be * freed if the inode is the only allocated inode within * the extent. in this case all the disk resource backing @@ -865,11 +865,11 @@ int diWrite(tid_t tid, struct inode *ip) * any updates and are held until all updates are complete. * * PARAMETERS: - * ip - inode to be freed. + * ip - inode to be freed. * * RETURN VALUES: * 0 - success - * -EIO - i/o error. + * -EIO - i/o error. */ int diFree(struct inode *ip) { @@ -898,7 +898,7 @@ int diFree(struct inode *ip) */ iagno = INOTOIAG(inum); - /* make sure that the iag is contained within + /* make sure that the iag is contained within * the map. */ if (iagno >= imap->im_nextiag) { @@ -1013,7 +1013,7 @@ int diFree(struct inode *ip) /* update the free inode summary map for the extent if * freeing the inode means the extent will now have free - * inodes (i.e., the inode being freed is the first free + * inodes (i.e., the inode being freed is the first free * inode of extent), */ if (iagp->wmap[extno] == cpu_to_le32(ONES)) { @@ -1204,9 +1204,9 @@ int diFree(struct inode *ip) iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1); } - /* update the inode extent address and working map + /* update the inode extent address and working map * to reflect the free extent. - * the permanent map should have been updated already + * the permanent map should have been updated already * for the inode being freed. */ if (iagp->pmap[extno] != 0) { @@ -1218,7 +1218,7 @@ int diFree(struct inode *ip) /* update the free extent and free inode summary maps * to reflect the freed extent. - * the inode summary map is marked to indicate no inodes + * the inode summary map is marked to indicate no inodes * available for the freed extent. */ sword = extno >> L2EXTSPERSUM; @@ -1255,17 +1255,17 @@ int diFree(struct inode *ip) * start transaction to update block allocation map * for the inode extent freed; * - * N.B. AG_LOCK is released and iag will be released below, and + * N.B. AG_LOCK is released and iag will be released below, and * other thread may allocate inode from/reusing the ixad freed - * BUT with new/different backing inode extent from the extent - * to be freed by the transaction; + * BUT with new/different backing inode extent from the extent + * to be freed by the transaction; */ tid = txBegin(ipimap->i_sb, COMMIT_FORCE); mutex_lock(&JFS_IP(ipimap)->commit_mutex); - /* acquire tlock of the iag page of the freed ixad + /* acquire tlock of the iag page of the freed ixad * to force the page NOHOMEOK (even though no data is - * logged from the iag page) until NOREDOPAGE|FREEXTENT log + * logged from the iag page) until NOREDOPAGE|FREEXTENT log * for the free of the extent is committed; * write FREEXTENT|NOREDOPAGE log record * N.B. linelock is overlaid as freed extent descriptor; @@ -1284,8 +1284,8 @@ int diFree(struct inode *ip) * logredo needs the IAG number and IAG extent index in order * to ensure that the IMap is consistent. The least disruptive * way to pass these values through to the transaction manager - * is in the iplist array. - * + * is in the iplist array. + * * It's not pretty, but it works. */ iplist[1] = (struct inode *) (size_t)iagno; @@ -1340,20 +1340,20 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) /* * NAME: diAlloc(pip,dir,ip) * - * FUNCTION: allocate a disk inode from the inode working map + * FUNCTION: allocate a disk inode from the inode working map * for a fileset or aggregate. * * PARAMETERS: - * pip - pointer to incore inode for the parent inode. - * dir - TRUE if the new disk inode is for a directory. - * ip - pointer to a new inode + * pip - pointer to incore inode for the parent inode. + * dir - 'true' if the new disk inode is for a directory. + * ip - pointer to a new inode * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ -int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) +int diAlloc(struct inode *pip, bool dir, struct inode *ip) { int rc, ino, iagno, addext, extno, bitno, sword; int nwords, rem, i, agno; @@ -1372,10 +1372,10 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) JFS_IP(ip)->ipimap = ipimap; JFS_IP(ip)->fileset = FILESYSTEM_I; - /* for a directory, the allocation policy is to start + /* for a directory, the allocation policy is to start * at the ag level using the preferred ag. */ - if (dir == TRUE) { + if (dir) { agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap); AG_LOCK(imap, agno); goto tryag; @@ -1435,7 +1435,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) /* * try to allocate from the IAG */ - /* check if the inode may be allocated from the iag + /* check if the inode may be allocated from the iag * (i.e. the inode has free inodes or new extent can be added). */ if (iagp->nfreeinos || addext) { @@ -1490,7 +1490,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) * hint or, if appropriate (i.e. addext is true), allocate * an extent of free inodes at or following the extent * containing the hint. - * + * * the free inode and free extent summary maps are used * here, so determine the starting summary map position * and the number of words we'll have to examine. again, @@ -1641,7 +1641,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) * inodes should be added for the allocation group, with * the current request satisfied from this extent. if this * is the case, an attempt will be made to do just that. if - * this attempt fails or it has been determined that a new + * this attempt fails or it has been determined that a new * extent should not be added, an attempt is made to satisfy * the request by allocating an existing (backed) free inode * from the allocation group. @@ -1649,24 +1649,24 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) * PRE CONDITION: Already have the AG lock for this AG. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - allocation group to allocate from. - * dir - TRUE if the new disk inode is for a directory. - * ip - pointer to the new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - allocation group to allocate from. + * dir - 'true' if the new disk inode is for a directory. + * ip - pointer to the new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ static int -diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) +diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) { int rc, addext, numfree, numinos; - /* get the number of free and the number of backed disk + /* get the number of free and the number of backed disk * inodes currently within the ag. */ numfree = imap->im_agctl[agno].numfree; @@ -1682,7 +1682,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) * if there are a small number of free inodes or number of free * inodes is a small percentage of the number of backed inodes. */ - if (dir == TRUE) + if (dir) addext = (numfree < 64 || (numfree < 256 && ((numfree * 100) / numinos) <= 20)); @@ -1719,26 +1719,26 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) * specified primary group. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - primary allocation group (to avoid). - * dir - TRUE if the new disk inode is for a directory. - * ip - pointer to a new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - primary allocation group (to avoid). + * dir - 'true' if the new disk inode is for a directory. + * ip - pointer to a new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ static int -diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) +diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip) { int ag, rc; int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag; - /* try to allocate from the ags following agno up to + /* try to allocate from the ags following agno up to * the maximum ag number. */ for (ag = agno + 1; ag <= maxag; ag++) { @@ -1780,21 +1780,21 @@ diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) * * allocation occurs from the first iag on the list using * the iag's free inode summary map to find the leftmost - * free inode in the iag. - * + * free inode in the iag. + * * PRE CONDITION: Already have AG lock for this AG. - * + * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - allocation group. - * ip - pointer to new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - allocation group. + * ip - pointer to new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) { @@ -1867,7 +1867,7 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) return -EIO; } - /* compute the inode number within the iag. + /* compute the inode number within the iag. */ ino = (extno << L2INOSPEREXT) + rem; @@ -1892,17 +1892,17 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) /* * NAME: diAllocExt(imap,agno,ip) * - * FUNCTION: add a new extent of free inodes to an iag, allocating - * an inode from this extent to satisfy the current allocation - * request. - * + * FUNCTION: add a new extent of free inodes to an iag, allocating + * an inode from this extent to satisfy the current allocation + * request. + * * this routine first tries to find an existing iag with free * extents through the ag free extent list. if list is not * empty, the head of the list will be selected as the home * of the new extent of free inodes. otherwise (the list is * empty), a new iag will be allocated for the ag to contain * the extent. - * + * * once an iag has been selected, the free extent summary map * is used to locate a free extent within the iag and diNewExt() * is called to initialize the extent, with initialization @@ -1910,16 +1910,16 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) * for the purpose of satisfying this request. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - allocation group number. - * ip - pointer to new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - allocation group number. + * ip - pointer to new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) { @@ -2012,7 +2012,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) /* * NAME: diAllocBit(imap,iagp,ino) * - * FUNCTION: allocate a backed inode from an iag. + * FUNCTION: allocate a backed inode from an iag. * * this routine performs the mechanics of allocating a * specified inode from a backed extent. @@ -2025,19 +2025,19 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) * in the face of updates to multiple buffers. under this * approach, all required buffers are obtained before making * any updates and are held all are updates are complete. - * + * * PRE CONDITION: Already have buffer lock on iagp. Already have AG lock on * this AG. Must have read lock on imap inode. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagp - pointer to iag. - * ino - inode number to be allocated within the iag. + * imap - pointer to inode map control structure. + * iagp - pointer to iag. + * ino - inode number to be allocated within the iag. * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) { @@ -2172,19 +2172,19 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) * buffers. under this approach, all required buffers are * obtained before making any updates and are held until all * updates are complete. - * + * * PRE CONDITION: Already have buffer lock on iagp. Already have AG lock on * this AG. Must have read lock on imap inode. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagp - pointer to iag. - * extno - extent number. + * imap - pointer to inode map control structure. + * iagp - pointer to iag. + * extno - extent number. * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. */ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) { @@ -2432,34 +2432,34 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) /* * NAME: diNewIAG(imap,iagnop,agno) * - * FUNCTION: allocate a new iag for an allocation group. - * - * first tries to allocate the iag from the inode map - * iagfree list: - * if the list has free iags, the head of the list is removed + * FUNCTION: allocate a new iag for an allocation group. + * + * first tries to allocate the iag from the inode map + * iagfree list: + * if the list has free iags, the head of the list is removed * and returned to satisfy the request. * if the inode map's iag free list is empty, the inode map * is extended to hold a new iag. this new iag is initialized * and returned to satisfy the request. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagnop - pointer to an iag number set with the number of the + * imap - pointer to inode map control structure. + * iagnop - pointer to an iag number set with the number of the * newly allocated iag upon successful return. - * agno - allocation group number. + * agno - allocation group number. * bpp - Buffer pointer to be filled in with new IAG's buffer * * RETURN VALUES: * 0 - success. * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * -EIO - i/o error. * - * serialization: + * serialization: * AG lock held on entry/exit; * write lock on the map is held inside; * read lock on the map is held on successful completion; * - * note: new iag transaction: + * note: new iag transaction: * . synchronously write iag; * . write log of xtree and inode of imap; * . commit; @@ -2494,7 +2494,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) /* acquire the free iag lock */ IAGFREE_LOCK(imap); - /* if there are any iags on the inode map free iag list, + /* if there are any iags on the inode map free iag list, * allocate the iag from the head of the list. */ if (imap->im_freeiag >= 0) { @@ -2618,8 +2618,8 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) flush_metapage(mp); /* - * txCommit(COMMIT_FORCE) will synchronously write address - * index pages and inode after commit in careful update order + * txCommit(COMMIT_FORCE) will synchronously write address + * index pages and inode after commit in careful update order * of address index pages (right to left, bottom up); */ iplist[0] = ipimap; @@ -2678,11 +2678,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) * * FUNCTION: get the buffer for the specified iag within a fileset * or aggregate inode map. - * + * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagno - iag number. - * bpp - point to buffer pointer to be filled in on successful + * imap - pointer to inode map control structure. + * iagno - iag number. + * bpp - point to buffer pointer to be filled in on successful * exit. * * SERIALIZATION: @@ -2692,7 +2692,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) * * RETURN VALUES: * 0 - success. - * -EIO - i/o error. + * -EIO - i/o error. */ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp) { @@ -2718,8 +2718,8 @@ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp) * the specified bit position. * * PARAMETERS: - * word - word to be examined. - * start - starting bit position. + * word - word to be examined. + * start - starting bit position. * * RETURN VALUES: * bit position of first free bit in the word or 32 if @@ -2740,24 +2740,24 @@ static int diFindFree(u32 word, int start) /* * NAME: diUpdatePMap() - * - * FUNCTION: Update the persistent map in an IAG for the allocation or + * + * FUNCTION: Update the persistent map in an IAG for the allocation or * freeing of the specified inode. - * + * * PRE CONDITIONS: Working map has already been updated for allocate. * * PARAMETERS: * ipimap - Incore inode map inode * inum - Number of inode to mark in permanent map - * is_free - If TRUE indicates inode should be marked freed, otherwise + * is_free - If 'true' indicates inode should be marked freed, otherwise * indicates inode should be marked allocated. * - * RETURN VALUES: + * RETURN VALUES: * 0 for success */ int diUpdatePMap(struct inode *ipimap, - unsigned long inum, boolean_t is_free, struct tblock * tblk) + unsigned long inum, bool is_free, struct tblock * tblk) { int rc; struct iag *iagp; @@ -2793,17 +2793,17 @@ diUpdatePMap(struct inode *ipimap, extno = ino >> L2INOSPEREXT; bitno = ino & (INOSPEREXT - 1); mask = HIGHORDER >> bitno; - /* + /* * mark the inode free in persistent map: */ - if (is_free == TRUE) { + if (is_free) { /* The inode should have been allocated both in working * map and in persistent map; * the inode will be freed from working map at the release * of last reference release; */ if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) { - jfs_error(ipimap->i_sb, + jfs_error(ipimap->i_sb, "diUpdatePMap: inode %ld not marked as " "allocated in wmap!", inum); } @@ -2877,8 +2877,8 @@ diUpdatePMap(struct inode *ipimap, * diExtendFS() * * function: update imap for extendfs(); - * - * note: AG size has been increased s.t. each k old contiguous AGs are + * + * note: AG size has been increased s.t. each k old contiguous AGs are * coalesced into a new AG; */ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) @@ -2897,7 +2897,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) atomic_read(&imap->im_numfree)); /* - * reconstruct imap + * reconstruct imap * * coalesce contiguous k (newAGSize/oldAGSize) AGs; * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn; @@ -2931,7 +2931,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) } /* leave free iag in the free iag list */ - if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { + if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { release_metapage(bp); continue; } diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h index 6e24465f0f9..4f9c346ed49 100644 --- a/fs/jfs/jfs_imap.h +++ b/fs/jfs/jfs_imap.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_IMAP @@ -45,13 +45,13 @@ /* get the starting block number of the 4K page of an inode extent * that contains ino. */ -#define INOPBLK(pxd,ino,l2nbperpg) (addressPXD((pxd)) + \ +#define INOPBLK(pxd,ino,l2nbperpg) (addressPXD((pxd)) + \ ((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg))) /* * inode allocation map: - * - * inode allocation map consists of + * + * inode allocation map consists of * . the inode map control page and * . inode allocation group pages (per 4096 inodes) * which are addressed by standard JFS xtree. @@ -159,11 +159,11 @@ struct inomap { #define im_maxag im_imap.in_maxag extern int diFree(struct inode *); -extern int diAlloc(struct inode *, boolean_t, struct inode *); +extern int diAlloc(struct inode *, bool, struct inode *); extern int diSync(struct inode *); /* external references */ extern int diUpdatePMap(struct inode *ipimap, unsigned long inum, - boolean_t is_free, struct tblock * tblk); + bool is_free, struct tblock * tblk); extern int diExtendFS(struct inode *ipimap, struct inode *ipbmap); extern int diMount(struct inode *); extern int diUnmount(struct inode *, int); diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index 54d73716ca8..94005584445 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h @@ -4,18 +4,18 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + */ #ifndef _H_JFS_INCORE #define _H_JFS_INCORE diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index bffaca9ae3a..4c67ed97682 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -61,7 +61,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) inode = new_inode(sb); if (!inode) { jfs_warn("ialloc: new_inode returned NULL!"); - return inode; + return ERR_PTR(-ENOMEM); } jfs_inode = JFS_IP(inode); @@ -69,9 +69,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode) rc = diAlloc(parent, S_ISDIR(mode), inode); if (rc) { jfs_warn("ialloc: diAlloc returned %d!", rc); - make_bad_inode(inode); + if (rc == -EIO) + make_bad_inode(inode); iput(inode); - return NULL; + return ERR_PTR(rc); } inode->i_uid = current->fsuid; @@ -97,7 +98,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); - return NULL; + return ERR_PTR(-EDQUOT); } inode->i_mode = mode; diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 1fc48df670c..0d06ccfaff0 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_INODE diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h index 70ac9f7d1e0..7d78e83d7c4 100644 --- a/fs/jfs/jfs_lock.h +++ b/fs/jfs/jfs_lock.h @@ -1,19 +1,19 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2001 - * Portions Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) International Business Machines Corp., 2000-2001 + * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_LOCK diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 3315f0b1fbc..b89c9aba046 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -337,7 +337,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, * PARAMETER: cd - commit descriptor * * RETURN: end-of-log address - * + * * serialization: LOG_LOCK() held on entry/exit */ static int @@ -554,7 +554,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, * PARAMETER: log * * RETURN: 0 - * + * * serialization: LOG_LOCK() held on entry/exit */ static int lmNextPage(struct jfs_log * log) @@ -656,7 +656,7 @@ static int lmNextPage(struct jfs_log * log) * page number - redrive pageout of the page at the head of * pageout queue until full page has been written. * - * RETURN: + * RETURN: * * NOTE: * LOGGC_LOCK serializes log group commit queue, and @@ -920,10 +920,10 @@ static void lmPostGC(struct lbuf * bp) * this code is called again. * * PARAMETERS: log - log structure - * hard_sync - 1 to force all metadata to be written + * hard_sync - 1 to force all metadata to be written * * RETURN: 0 - * + * * serialization: LOG_LOCK() held on entry/exit */ static int lmLogSync(struct jfs_log * log, int hard_sync) @@ -1052,7 +1052,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync) * FUNCTION: write log SYNCPT record for specified log * * PARAMETERS: log - log structure - * hard_sync - set to 1 to force metadata to be written + * hard_sync - set to 1 to force metadata to be written */ void jfs_syncpt(struct jfs_log *log, int hard_sync) { LOG_LOCK(log); @@ -1067,7 +1067,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync) * insert filesystem in the active list of the log. * * PARAMETER: ipmnt - file system mount inode - * iplog - log inode (out) + * iplog - log inode (out) * * RETURN: * @@ -1082,7 +1082,7 @@ int lmLogOpen(struct super_block *sb) if (sbi->flag & JFS_NOINTEGRITY) return open_dummy_log(sb); - + if (sbi->mntflag & JFS_INLINELOG) return open_inline_log(sb); @@ -1131,7 +1131,7 @@ int lmLogOpen(struct super_block *sb) log->bdev = bdev; memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid)); - + /* * initialize log: */ @@ -1253,13 +1253,13 @@ static int open_dummy_log(struct super_block *sb) * initialize the log from log superblock. * set the log state in the superblock to LOGMOUNT and * write SYNCPT log record. - * + * * PARAMETER: log - log structure * * RETURN: 0 - if ok * -EINVAL - bad log magic number or superblock dirty * error returned from logwait() - * + * * serialization: single first open thread */ int lmLogInit(struct jfs_log * log) @@ -1297,7 +1297,7 @@ int lmLogInit(struct jfs_log * log) if (!test_bit(log_INLINELOG, &log->flag)) log->l2bsize = L2LOGPSIZE; - + /* check for disabled journaling to disk */ if (log->no_integrity) { /* @@ -1651,7 +1651,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait) * PARAMETER: log - log inode * * RETURN: 0 - success - * + * * serialization: single last close thread */ int lmLogShutdown(struct jfs_log * log) @@ -1677,7 +1677,7 @@ int lmLogShutdown(struct jfs_log * log) lrd.type = cpu_to_le16(LOG_SYNCPT); lrd.length = 0; lrd.log.syncpt.sync = 0; - + lsn = lmWriteRecord(log, NULL, &lrd, NULL); bp = log->bp; lp = (struct logpage *) bp->l_ldata; @@ -1703,7 +1703,7 @@ int lmLogShutdown(struct jfs_log * log) jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d", lsn, log->page, log->eor); - out: + out: /* * shutdown per log i/o */ @@ -1769,7 +1769,7 @@ static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi, lbmFree(bpsuper); return -EIO; } - + } /* diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index 8c6909b8001..a53fb17ea21 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_LOGMGR @@ -35,19 +35,19 @@ /* * log logical volume * - * a log is used to make the commit operation on journalled + * a log is used to make the commit operation on journalled * files within the same logical volume group atomic. * a log is implemented with a logical volume. - * there is one log per logical volume group. + * there is one log per logical volume group. * * block 0 of the log logical volume is not used (ipl etc). * block 1 contains a log "superblock" and is used by logFormat(), - * lmLogInit(), lmLogShutdown(), and logRedo() to record status - * of the log but is not otherwise used during normal processing. + * lmLogInit(), lmLogShutdown(), and logRedo() to record status + * of the log but is not otherwise used during normal processing. * blocks 2 - (N-1) are used to contain log records. * - * when a volume group is varied-on-line, logRedo() must have - * been executed before the file systems (logical volumes) in + * when a volume group is varied-on-line, logRedo() must have + * been executed before the file systems (logical volumes) in * the volume group can be mounted. */ /* @@ -97,26 +97,26 @@ struct logsuper { * log logical page * * (this comment should be rewritten !) - * the header and trailer structures (h,t) will normally have + * the header and trailer structures (h,t) will normally have * the same page and eor value. - * An exception to this occurs when a complete page write is not + * An exception to this occurs when a complete page write is not * accomplished on a power failure. Since the hardware may "split write" - * sectors in the page, any out of order sequence may occur during powerfail + * sectors in the page, any out of order sequence may occur during powerfail * and needs to be recognized during log replay. The xor value is * an "exclusive or" of all log words in the page up to eor. This * 32 bit eor is stored with the top 16 bits in the header and the * bottom 16 bits in the trailer. logredo can easily recognize pages - * that were not completed by reconstructing this eor and checking + * that were not completed by reconstructing this eor and checking * the log page. * - * Previous versions of the operating system did not allow split - * writes and detected partially written records in logredo by - * ordering the updates to the header, trailer, and the move of data - * into the logdata area. The order: (1) data is moved (2) header - * is updated (3) trailer is updated. In logredo, when the header - * differed from the trailer, the header and trailer were reconciled - * as follows: if h.page != t.page they were set to the smaller of - * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) + * Previous versions of the operating system did not allow split + * writes and detected partially written records in logredo by + * ordering the updates to the header, trailer, and the move of data + * into the logdata area. The order: (1) data is moved (2) header + * is updated (3) trailer is updated. In logredo, when the header + * differed from the trailer, the header and trailer were reconciled + * as follows: if h.page != t.page they were set to the smaller of + * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) * h.eor != t.eor they were set to the smaller of their two values. */ struct logpage { @@ -147,20 +147,20 @@ struct logpage { * in a page, pages are written to temporary paging space if * if they must be written to disk before commit, and i/o is * scheduled for modified pages to their home location after - * the log records containing the after values and the commit + * the log records containing the after values and the commit * record is written to the log on disk, undo discards the copy * in main-memory.) * - * a log record consists of a data area of variable length followed by + * a log record consists of a data area of variable length followed by * a descriptor of fixed size LOGRDSIZE bytes. - * the data area is rounded up to an integral number of 4-bytes and + * the data area is rounded up to an integral number of 4-bytes and * must be no longer than LOGPSIZE. - * the descriptor is of size of multiple of 4-bytes and aligned on a - * 4-byte boundary. + * the descriptor is of size of multiple of 4-bytes and aligned on a + * 4-byte boundary. * records are packed one after the other in the data area of log pages. - * (sometimes a DUMMY record is inserted so that at least one record ends + * (sometimes a DUMMY record is inserted so that at least one record ends * on every page or the longest record is placed on at most two pages). - * the field eor in page header/trailer points to the byte following + * the field eor in page header/trailer points to the byte following * the last record on a page. */ @@ -270,11 +270,11 @@ struct lrd { /* * NOREDOINOEXT: the inode extent is freed * - * do not apply after-image records which precede this - * record in the log with the any of the 4 page block - * numbers in this inode extent. - * - * NOTE: The fileset and pxd fields MUST remain in + * do not apply after-image records which precede this + * record in the log with the any of the 4 page block + * numbers in this inode extent. + * + * NOTE: The fileset and pxd fields MUST remain in * the same fields in the REDOPAGE record format. * */ @@ -319,12 +319,10 @@ struct lrd { * do not apply records which precede this record in the log * with the same inode number. * - * NOREDILE must be the first to be written at commit + * NOREDOFILE must be the first to be written at commit * (last to be read in logredo()) - it prevents * replay of preceding updates of all preceding generations - * of the inumber esp. the on-disk inode itself, - * but does NOT prevent - * replay of the + * of the inumber esp. the on-disk inode itself. */ struct { __le32 fileset; /* 4: fileset number */ @@ -332,7 +330,7 @@ struct lrd { } noredofile; /* - * ? NEWPAGE: + * ? NEWPAGE: * * metadata type dependent */ @@ -464,7 +462,7 @@ struct lbuf { s64 l_blkno; /* 8: log page block number */ caddr_t l_ldata; /* 4: data page */ struct page *l_page; /* The page itself */ - uint l_offset; /* Offset of l_ldata within the page */ + uint l_offset; /* Offset of l_ldata within the page */ wait_queue_head_t l_ioevent; /* 4: i/o done event */ }; diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index f5afc129d6b..0cccd1c39d7 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -461,7 +461,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) goto add_failed; if (!bio->bi_size) goto dump_bio; - + submit_bio(WRITE, bio); } if (redirty) @@ -648,7 +648,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, jfs_err("logical_size = %d, size = %d", mp->logical_size, size); dump_stack(); - goto unlock; + goto unlock; } mp->count++; lock_metapage(mp); @@ -658,7 +658,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, "__get_metapage: using a " "discarded metapage"); discard_metapage(mp); - goto unlock; + goto unlock; } clear_bit(META_discard, &mp->flag); } diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h index d17a3290f5a..d94f8d9e87d 100644 --- a/fs/jfs/jfs_metapage.h +++ b/fs/jfs/jfs_metapage.h @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_METAPAGE @@ -33,7 +33,7 @@ struct metapage { unsigned long flag; /* See Below */ unsigned long count; /* Reference count */ void *data; /* Data pointer */ - sector_t index; /* block address of page */ + sector_t index; /* block address of page */ wait_queue_head_t wait; /* implementation */ @@ -65,10 +65,10 @@ extern struct metapage *__get_metapage(struct inode *inode, int absolute, unsigned long new); #define read_metapage(inode, lblock, size, absolute)\ - __get_metapage(inode, lblock, size, absolute, FALSE) + __get_metapage(inode, lblock, size, absolute, false) #define get_metapage(inode, lblock, size, absolute)\ - __get_metapage(inode, lblock, size, absolute, TRUE) + __get_metapage(inode, lblock, size, absolute, true) extern void release_metapage(struct metapage *); extern void grab_metapage(struct metapage *); diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index 032d111bc33..4dd47983489 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -21,18 +21,18 @@ * * note: file system in transition to aggregate/fileset: * - * file system mount is interpreted as the mount of aggregate, - * if not already mounted, and mount of the single/only fileset in + * file system mount is interpreted as the mount of aggregate, + * if not already mounted, and mount of the single/only fileset in * the aggregate; * * a file system/aggregate is represented by an internal inode * (aka mount inode) initialized with aggregate superblock; - * each vfs represents a fileset, and points to its "fileset inode + * each vfs represents a fileset, and points to its "fileset inode * allocation map inode" (aka fileset inode): - * (an aggregate itself is structured recursively as a filset: - * an internal vfs is constructed and points to its "fileset inode - * allocation map inode" (aka aggregate inode) where each inode - * represents a fileset inode) so that inode number is mapped to + * (an aggregate itself is structured recursively as a filset: + * an internal vfs is constructed and points to its "fileset inode + * allocation map inode" (aka aggregate inode) where each inode + * represents a fileset inode) so that inode number is mapped to * on-disk inode in uniform way at both aggregate and fileset level; * * each vnode/inode of a fileset is linked to its vfs (to facilitate @@ -41,7 +41,7 @@ * per aggregate information, e.g., block size, etc.) as well as * its file set inode. * - * aggregate + * aggregate * ipmnt * mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap; * fileset vfs -> vp(1) <-> ... <-> vp(n) <->vproot; @@ -88,7 +88,7 @@ int jfs_mount(struct super_block *sb) struct inode *ipbmap = NULL; /* - * read/validate superblock + * read/validate superblock * (initialize mount inode from the superblock) */ if ((rc = chkSuper(sb))) { @@ -238,7 +238,7 @@ int jfs_mount(struct super_block *sb) */ int jfs_mount_rw(struct super_block *sb, int remount) { - struct jfs_sb_info *sbi = JFS_SBI(sb); + struct jfs_sb_info *sbi = JFS_SBI(sb); int rc; /* @@ -291,7 +291,7 @@ int jfs_mount_rw(struct super_block *sb, int remount) /* * chkSuper() * - * validate the superblock of the file system to be mounted and + * validate the superblock of the file system to be mounted and * get the file system parameters. * * returns @@ -426,7 +426,7 @@ int updateSuper(struct super_block *sb, uint state) jfs_err("updateSuper: bad state"); } else if (sbi->state == FM_DIRTY) return 0; - + if ((rc = readSuper(sb, &bh))) return rc; @@ -486,9 +486,9 @@ int readSuper(struct super_block *sb, struct buffer_head **bpp) * for this file system past this point in log. * it is harmless if mount fails. * - * note: MOUNT record is at aggregate level, not at fileset level, + * note: MOUNT record is at aggregate level, not at fileset level, * since log records of previous mounts of a fileset - * (e.g., AFTER record of extent allocation) have to be processed + * (e.g., AFTER record of extent allocation) have to be processed * to update block allocation map at aggregate level. */ static int logMOUNT(struct super_block *sb) diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h index 682cf1a68a1..884fc21ab8e 100644 --- a/fs/jfs/jfs_superblock.h +++ b/fs/jfs/jfs_superblock.h @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_SUPERBLOCK @@ -21,14 +21,14 @@ /* * make the magic number something a human could read */ -#define JFS_MAGIC "JFS1" /* Magic word */ +#define JFS_MAGIC "JFS1" /* Magic word */ #define JFS_VERSION 2 /* Version number: Version 2 */ #define LV_NAME_SIZE 11 /* MUST BE 11 for OS/2 boot sector */ -/* - * aggregate superblock +/* + * aggregate superblock * * The name superblock is too close to super_block, so the name has been * changed to jfs_superblock. The utilities are still using the old name. @@ -40,7 +40,7 @@ struct jfs_superblock { __le64 s_size; /* 8: aggregate size in hardware/LVM blocks; * VFS: number of blocks */ - __le32 s_bsize; /* 4: aggregate block size in bytes; + __le32 s_bsize; /* 4: aggregate block size in bytes; * VFS: fragment size */ __le16 s_l2bsize; /* 2: log2 of s_bsize */ @@ -54,7 +54,7 @@ struct jfs_superblock { __le32 s_flag; /* 4: aggregate attributes: * see jfs_filsys.h */ - __le32 s_state; /* 4: mount/unmount/recovery state: + __le32 s_state; /* 4: mount/unmount/recovery state: * see jfs_filsys.h */ __le32 s_compress; /* 4: > 0 if data compression */ @@ -75,11 +75,11 @@ struct jfs_superblock { struct timestruc_t s_time; /* 8: time last updated */ __le32 s_fsckloglen; /* 4: Number of filesystem blocks reserved for - * the fsck service log. + * the fsck service log. * N.B. These blocks are divided among the * versions kept. This is not a per * version size. - * N.B. These blocks are included in the + * N.B. These blocks are included in the * length field of s_fsckpxd. */ s8 s_fscklog; /* 1: which fsck service log is most recent @@ -87,7 +87,7 @@ struct jfs_superblock { * 1 => the first one * 2 => the 2nd one */ - char s_fpack[11]; /* 11: file system volume name + char s_fpack[11]; /* 11: file system volume name * N.B. This must be 11 bytes to * conform with the OS/2 BootSector * requirements diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 3856efc399c..81f6f04af19 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -2026,8 +2026,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, * truncate entry XAD[twm == next - 1]: */ if (twm == next - 1) { - struct pxd_lock *pxdlock; - /* format a maplock for txUpdateMap() to update bmap * to free truncated delta extent of the truncated * entry XAD[next - 1]; @@ -2393,7 +2391,7 @@ static void txUpdateMap(struct tblock * tblk) * unlock mapper/write lock */ if (tblk->xflag & COMMIT_CREATE) { - diUpdatePMap(ipimap, tblk->ino, FALSE, tblk); + diUpdatePMap(ipimap, tblk->ino, false, tblk); /* update persistent block allocation map * for the allocation of inode extent; */ @@ -2403,7 +2401,7 @@ static void txUpdateMap(struct tblock * tblk) txAllocPMap(ipimap, (struct maplock *) & pxdlock, tblk); } else if (tblk->xflag & COMMIT_DELETE) { ip = tblk->u.ip; - diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk); + diUpdatePMap(ipimap, ip->i_ino, true, tblk); iput(ip); } } @@ -2451,7 +2449,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, if (xad->flag & (XAD_NEW | XAD_EXTENDED)) { xaddr = addressXAD(xad); xlen = lengthXAD(xad); - dbUpdatePMap(ipbmap, FALSE, xaddr, + dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk); xad->flag &= ~(XAD_NEW | XAD_EXTENDED); jfs_info("allocPMap: xaddr:0x%lx xlen:%d", @@ -2462,7 +2460,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, pxdlock = (struct pxd_lock *) maplock; xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); - dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); + dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk); jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckALLOCPXDLIST) */ @@ -2471,7 +2469,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, for (n = 0; n < pxdlistlock->count; n++, pxd++) { xaddr = addressPXD(pxd); xlen = lengthPXD(pxd); - dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, + dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk); jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); @@ -2513,7 +2511,7 @@ void txFreeMap(struct inode *ip, if (!(xad->flag & XAD_NEW)) { xaddr = addressXAD(xad); xlen = lengthXAD(xad); - dbUpdatePMap(ipbmap, TRUE, xaddr, + dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen, tblk); jfs_info("freePMap: xaddr:0x%lx " "xlen:%d", @@ -2524,7 +2522,7 @@ void txFreeMap(struct inode *ip, pxdlock = (struct pxd_lock *) maplock; xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); - dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, + dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen, tblk); jfs_info("freePMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); @@ -2535,7 +2533,7 @@ void txFreeMap(struct inode *ip, for (n = 0; n < pxdlistlock->count; n++, pxd++) { xaddr = addressPXD(pxd); xlen = lengthPXD(pxd); - dbUpdatePMap(ipbmap, TRUE, xaddr, + dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen, tblk); jfs_info("freePMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h index 0e4dc4514c4..7863cf21afc 100644 --- a/fs/jfs/jfs_txnmgr.h +++ b/fs/jfs/jfs_txnmgr.h @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_TXNMGR @@ -179,7 +179,7 @@ struct linelock { /* (8) */ struct lv lv[20]; /* 40: */ -}; /* (48) */ +}; /* (48) */ #define dt_lock linelock @@ -211,8 +211,8 @@ struct xtlock { * at tlock.lock/linelock: watch for alignment; * N.B. next field may be set by linelock, and should not * be modified by maplock; - * N.B. index of the first pxdlock specifies index of next - * free maplock (i.e., number of maplock) in the tlock; + * N.B. index of the first pxdlock specifies index of next + * free maplock (i.e., number of maplock) in the tlock; */ struct maplock { lid_t next; /* 2: */ diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h index 5bfad39a207..09b25295868 100644 --- a/fs/jfs/jfs_types.h +++ b/fs/jfs/jfs_types.h @@ -57,10 +57,6 @@ struct timestruc_t { #define HIGHORDER 0x80000000u /* high order bit on */ #define ONES 0xffffffffu /* all bit on */ -typedef int boolean_t; -#define TRUE 1 -#define FALSE 0 - /* * logical xd (lxd) */ diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c index 21eaf7ac0fc..a386f48c73f 100644 --- a/fs/jfs/jfs_umount.c +++ b/fs/jfs/jfs_umount.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -22,8 +22,8 @@ * note: file system in transition to aggregate/fileset: * (ref. jfs_mount.c) * - * file system unmount is interpreted as mount of the single/only - * fileset in the aggregate and, if unmount of the last fileset, + * file system unmount is interpreted as mount of the single/only + * fileset in the aggregate and, if unmount of the last fileset, * as unmount of the aggerate; */ @@ -60,13 +60,13 @@ int jfs_umount(struct super_block *sb) jfs_info("UnMount JFS: sb:0x%p", sb); /* - * update superblock and close log + * update superblock and close log * * if mounted read-write and log based recovery was enabled */ if ((log = sbi->log)) /* - * Wait for outstanding transactions to be written to log: + * Wait for outstanding transactions to be written to log: */ jfs_flush_journal(log, 2); @@ -112,17 +112,17 @@ int jfs_umount(struct super_block *sb) /* * ensure all file system file pages are propagated to their - * home blocks on disk (and their in-memory buffer pages are + * home blocks on disk (and their in-memory buffer pages are * invalidated) BEFORE updating file system superblock state - * (to signify file system is unmounted cleanly, and thus in - * consistent state) and log superblock active file system + * (to signify file system is unmounted cleanly, and thus in + * consistent state) and log superblock active file system * list (to signify skip logredo()). */ if (log) { /* log = NULL if read-only mount */ updateSuper(sb, FM_CLEAN); /* - * close log: + * close log: * * remove file system from log active file system list. */ @@ -142,7 +142,7 @@ int jfs_umount_rw(struct super_block *sb) return 0; /* - * close log: + * close log: * * remove file system from log active file system list. */ diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c index f327decfb15..c7de6f5bbef 100644 --- a/fs/jfs/jfs_unicode.c +++ b/fs/jfs/jfs_unicode.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -57,8 +57,8 @@ int jfs_strfromUCS_le(char *to, const __le16 * from, warn--; warn_again--; printk(KERN_ERR - "non-latin1 character 0x%x found in JFS file name\n", - le16_to_cpu(from[i])); + "non-latin1 character 0x%x found in JFS file name\n", + le16_to_cpu(from[i])); printk(KERN_ERR "mount with iocharset=utf8 to access\n"); } @@ -124,7 +124,7 @@ int get_UCSname(struct component_name * uniName, struct dentry *dentry) kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS); if (uniName->name == NULL) - return -ENOSPC; + return -ENOMEM; uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name, length, nls_tab); diff --git a/fs/jfs/jfs_unicode.h b/fs/jfs/jfs_unicode.h index 69e25ebe87a..3fbb3a22559 100644 --- a/fs/jfs/jfs_unicode.h +++ b/fs/jfs/jfs_unicode.h @@ -1,19 +1,19 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 - * Portions Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 + * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_UNICODE diff --git a/fs/jfs/jfs_uniupr.c b/fs/jfs/jfs_uniupr.c index 4ab185d2630..cfe50666d31 100644 --- a/fs/jfs/jfs_uniupr.c +++ b/fs/jfs/jfs_uniupr.c @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index 25e9990bccd..88b6cc535bf 100644 --- a/fs/jfs/jfs_xattr.h +++ b/fs/jfs/jfs_xattr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index e72f4ebb6e9..e98eb03e531 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* @@ -2428,7 +2428,7 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p); * return: */ int xtAppend(tid_t tid, /* transaction id */ - struct inode *ip, int xflag, s64 xoff, s32 maxblocks, + struct inode *ip, int xflag, s64 xoff, s32 maxblocks, s32 * xlenp, /* (in/out) */ s64 * xaddrp, /* (in/out) */ int flag) @@ -2499,7 +2499,7 @@ int xtAppend(tid_t tid, /* transaction id */ pxdlist.maxnpxd = pxdlist.npxd = 0; pxd = &pxdlist.pxd[0]; nblocks = JFS_SBI(ip->i_sb)->nbperpage; - for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) { + for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) { if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) { PXDaddress(pxd, xaddr); PXDlength(pxd, nblocks); @@ -2514,7 +2514,7 @@ int xtAppend(tid_t tid, /* transaction id */ goto out; } - xlen = min(xlen, maxblocks); + xlen = min(xlen, maxblocks); /* * allocate data extent requested @@ -2964,7 +2964,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ cmSetXD(ip, cp, pno, dxaddr, nblks); /* release the cbuf, mark it as modified */ - cmPut(cp, TRUE); + cmPut(cp, true); dxaddr += nblks; sxaddr += nblks; diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h index af668a80b40..164f6f2b101 100644 --- a/fs/jfs/jfs_xtree.h +++ b/fs/jfs/jfs_xtree.h @@ -1,18 +1,18 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_JFS_XTREE diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 295268ad231..a6a8c16c872 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -41,7 +41,7 @@ static s64 commitZeroLink(tid_t, struct inode *); /* * NAME: free_ea_wmap(inode) * - * FUNCTION: free uncommitted extended attributes from working map + * FUNCTION: free uncommitted extended attributes from working map * */ static inline void free_ea_wmap(struct inode *inode) @@ -62,7 +62,7 @@ static inline void free_ea_wmap(struct inode *inode) * FUNCTION: create a regular file in the parent directory <dip> * with name = <from dentry> and mode = <mode> * - * PARAMETER: dip - parent directory vnode + * PARAMETER: dip - parent directory vnode * dentry - dentry of new file * mode - create mode (rwxrwxrwx). * nd- nd struct @@ -97,8 +97,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, * begin the transaction before we search the directory. */ ip = ialloc(dip, mode); - if (ip == NULL) { - rc = -ENOSPC; + if (IS_ERR(ip)) { + rc = PTR_ERR(ip); goto out2; } @@ -190,7 +190,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, * FUNCTION: create a child directory in the parent directory <dip> * with name = <from dentry> and mode = <mode> * - * PARAMETER: dip - parent directory vnode + * PARAMETER: dip - parent directory vnode * dentry - dentry of child directory * mode - create mode (rwxrwxrwx). * @@ -231,8 +231,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) * begin the transaction before we search the directory. */ ip = ialloc(dip, S_IFDIR | mode); - if (ip == NULL) { - rc = -ENOSPC; + if (IS_ERR(ip)) { + rc = PTR_ERR(ip); goto out2; } @@ -292,7 +292,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) mark_inode_dirty(ip); /* update parent directory inode */ - dip->i_nlink++; /* for '..' from child directory */ + inc_nlink(dip); /* for '..' from child directory */ dip->i_ctime = dip->i_mtime = CURRENT_TIME; mark_inode_dirty(dip); @@ -324,7 +324,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) * * FUNCTION: remove a link to child directory * - * PARAMETER: dip - parent inode + * PARAMETER: dip - parent inode * dentry - child directory dentry * * RETURN: -EINVAL - if name is . or .. @@ -332,10 +332,10 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) * errors from subroutines * * note: - * if other threads have the directory open when the last link - * is removed, the "." and ".." entries, if present, are removed before - * rmdir() returns and no new entries may be created in the directory, - * but the directory is not removed until the last reference to + * if other threads have the directory open when the last link + * is removed, the "." and ".." entries, if present, are removed before + * rmdir() returns and no new entries may be created in the directory, + * but the directory is not removed until the last reference to * the directory is released (cf.unlink() of regular file). */ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) @@ -393,9 +393,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) /* update parent directory's link count corresponding * to ".." entry of the target directory deleted */ - dip->i_nlink--; dip->i_ctime = dip->i_mtime = CURRENT_TIME; - mark_inode_dirty(dip); + inode_dec_link_count(dip); /* * OS/2 could have created EA and/or ACL @@ -415,7 +414,7 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) JFS_IP(ip)->acl.flag = 0; /* mark the target directory as deleted */ - ip->i_nlink = 0; + clear_nlink(ip); mark_inode_dirty(ip); rc = txCommit(tid, 2, &iplist[0], 0); @@ -447,11 +446,11 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) /* * NAME: jfs_unlink(dip, dentry) * - * FUNCTION: remove a link to object <vp> named by <name> + * FUNCTION: remove a link to object <vp> named by <name> * from parent directory <dvp> * - * PARAMETER: dip - inode of parent directory - * dentry - dentry of object to be removed + * PARAMETER: dip - inode of parent directory + * dentry - dentry of object to be removed * * RETURN: errors from subroutines * @@ -515,8 +514,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) mark_inode_dirty(dip); /* update target's inode */ - ip->i_nlink--; - mark_inode_dirty(ip); + inode_dec_link_count(ip); /* * commit zero link count object @@ -600,7 +598,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) * * FUNCTION: for non-directory, called by jfs_remove(), * truncate a regular file, directory or symbolic - * link to zero length. return 0 if type is not + * link to zero length. return 0 if type is not * one of these. * * if the file is currently associated with a VM segment @@ -610,7 +608,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) * map by ctrunc1. * if there is no VM segment on entry, the resources are * freed in both work and permanent map. - * (? for temporary file - memory object is cached even + * (? for temporary file - memory object is cached even * after no reference: * reference count > 0 - ) * @@ -664,7 +662,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip) /* * free xtree/data (truncate to zero length): - * free xtree/data pages from cache if COMMIT_PWMAP, + * free xtree/data pages from cache if COMMIT_PWMAP, * free xtree/data blocks from persistent block map, and * free xtree/data blocks from working block map if COMMIT_PWMAP; */ @@ -679,7 +677,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip) * NAME: jfs_free_zero_link() * * FUNCTION: for non-directory, called by iClose(), - * free resources of a file from cache and WORKING map + * free resources of a file from cache and WORKING map * for a file previously committed with zero link count * while associated with a pager object, * @@ -764,7 +762,7 @@ void jfs_free_zero_link(struct inode *ip) * FUNCTION: create a link to <vp> by the name = <name> * in the parent directory <dvp> * - * PARAMETER: vp - target object + * PARAMETER: vp - target object * dvp - parent directory of new link * name - name of new link to target object * crp - credential @@ -824,7 +822,7 @@ static int jfs_link(struct dentry *old_dentry, goto free_dname; /* update object inode */ - ip->i_nlink++; /* for new link */ + inc_nlink(ip); /* for new link */ ip->i_ctime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME; mark_inode_dirty(dir); @@ -835,7 +833,7 @@ static int jfs_link(struct dentry *old_dentry, rc = txCommit(tid, 2, &iplist[0], 0); if (rc) { - ip->i_nlink--; + ip->i_nlink--; /* never instantiated */ iput(ip); } else d_instantiate(dentry, ip); @@ -860,8 +858,8 @@ static int jfs_link(struct dentry *old_dentry, * in directory <dip> * * PARAMETER: dip - parent directory vnode - * dentry - dentry of symbolic link - * name - the path name of the existing object + * dentry - dentry of symbolic link + * name - the path name of the existing object * that will be the source of the link * * RETURN: errors from subroutines @@ -908,8 +906,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, * (iAlloc() returns new, locked inode) */ ip = ialloc(dip, S_IFLNK | 0777); - if (ip == NULL) { - rc = -ENOSPC; + if (IS_ERR(ip)) { + rc = PTR_ERR(ip); goto out2; } @@ -928,7 +926,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, tblk->u.ixpxd = JFS_IP(ip)->ixpxd; /* fix symlink access permission - * (dir_create() ANDs in the u.u_cmask, + * (dir_create() ANDs in the u.u_cmask, * but symlinks really need to be 777 access) */ ip->i_mode |= 0777; @@ -969,7 +967,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, ip->i_mapping->a_ops = &jfs_aops; /* - * even though the data of symlink object (source + * even though the data of symlink object (source * path name) is treated as non-journaled user data, * it is read/written thru buffer cache for performance. */ @@ -980,7 +978,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, xlen = xsize >> JFS_SBI(sb)->l2bsize; if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) { txAbort(tid, 0); - rc = -ENOSPC; goto out3; } extent = xaddr; @@ -1155,9 +1152,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_ip->i_ino, JFS_RENAME); if (rc) goto out4; - new_ip->i_nlink--; + drop_nlink(new_ip); if (S_ISDIR(new_ip->i_mode)) { - new_ip->i_nlink--; + drop_nlink(new_ip); if (new_ip->i_nlink) { mutex_unlock(&JFS_IP(new_ip)->commit_mutex); if (old_dir != new_dir) @@ -1178,7 +1175,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, /* free block resources */ if ((new_size = commitZeroLink(tid, new_ip)) < 0) { txAbort(tid, 1); /* Marks FS Dirty */ - rc = new_size; + rc = new_size; goto out4; } tblk = tid_to_tblock(tid); @@ -1208,7 +1205,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out4; } if (S_ISDIR(old_ip->i_mode)) - new_dir->i_nlink++; + inc_nlink(new_dir); } /* * Remove old directory entry @@ -1223,7 +1220,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out4; } if (S_ISDIR(old_ip->i_mode)) { - old_dir->i_nlink--; + drop_nlink(old_dir); if (old_dir != new_dir) { /* * Change inode number of parent for moved directory @@ -1294,7 +1291,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, new_size = xtTruncate_pmap(tid, new_ip, new_size); if (new_size < 0) { txAbort(tid, 1); - rc = new_size; + rc = new_size; } else rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC); txEnd(tid); @@ -1352,8 +1349,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, goto out; ip = ialloc(dir, mode); - if (ip == NULL) { - rc = -ENOSPC; + if (IS_ERR(ip)) { + rc = PTR_ERR(ip); goto out1; } jfs_ip = JFS_IP(ip); diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index 45180361871..79d625f3f73 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 143bcd1d5ea..9c1c6e0e633 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -82,7 +82,7 @@ static void jfs_handle_error(struct super_block *sb) "as read-only\n", sb->s_id); sb->s_flags |= MS_RDONLY; - } + } /* nothing is done for continue beyond marking the superblock dirty */ } @@ -422,7 +422,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL); if (!sbi) - return -ENOSPC; + return -ENOMEM; sb->s_fs_info = sbi; sbi->sb = sb; sbi->uid = sbi->gid = sbi->umask = -1; @@ -775,7 +775,7 @@ static int __init init_jfs_fs(void) int rc; jfs_inode_cachep = - kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, + kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, init_once, NULL); if (jfs_inode_cachep == NULL) diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index 16477b3835e..cee43f36f51 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c @@ -3,16 +3,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 9bc5b7c055c..4c7985ebca9 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -57,7 +57,7 @@ * * 0 4 4 + EA_SIZE(ea1) * +------------+-------------------+--------------------+----- - * | Overall EA | First FEA Element | Second FEA Element | ..... + * | Overall EA | First FEA Element | Second FEA Element | ..... * | List Size | | | * +------------+-------------------+--------------------+----- * @@ -97,26 +97,26 @@ static inline int is_os2_xattr(struct jfs_ea *ea) */ if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) && !strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return FALSE; + return false; /* * Check for "user." */ if ((ea->namelen >= XATTR_USER_PREFIX_LEN) && !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) - return FALSE; + return false; /* * Check for "security." */ if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) && !strncmp(ea->name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) - return FALSE; + return false; /* * Check for "trusted." */ if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) && !strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) - return FALSE; + return false; /* * Add any other valid namespace prefixes here */ @@ -124,7 +124,7 @@ static inline int is_os2_xattr(struct jfs_ea *ea) /* * We assume it's OS/2's flat namespace */ - return TRUE; + return true; } static inline int name_size(struct jfs_ea *ea) @@ -155,9 +155,9 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf); /* * NAME: ea_write_inline - * + * * FUNCTION: Attempt to write an EA inline if area is available - * + * * PRE CONDITIONS: * Already verified that the specified EA is small enough to fit inline * @@ -216,10 +216,10 @@ static int ea_write_inline(struct inode *ip, struct jfs_ea_list *ealist, /* * NAME: ea_write - * + * * FUNCTION: Write an EA for an inode - * - * PRE CONDITIONS: EA has been verified + * + * PRE CONDITIONS: EA has been verified * * PARAMETERS: * ip - Inode pointer @@ -340,9 +340,9 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, /* * NAME: ea_read_inline - * + * * FUNCTION: Read an inlined EA into user's buffer - * + * * PARAMETERS: * ip - Inode pointer * ealist - Pointer to buffer to fill in with EA @@ -372,9 +372,9 @@ static int ea_read_inline(struct inode *ip, struct jfs_ea_list *ealist) /* * NAME: ea_read - * + * * FUNCTION: copy EA data into user's buffer - * + * * PARAMETERS: * ip - Inode pointer * ealist - Pointer to buffer to fill in with EA @@ -406,7 +406,7 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist) return -EIO; } - /* + /* * Figure out how many blocks were allocated when this EA list was * originally written to disk. */ @@ -443,14 +443,14 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist) /* * NAME: ea_get - * + * * FUNCTION: Returns buffer containing existing extended attributes. * The size of the buffer will be the larger of the existing * attributes size, or min_size. * * The buffer, which may be inlined in the inode or in the - * page cache must be release by calling ea_release or ea_put - * + * page cache must be release by calling ea_release or ea_put + * * PARAMETERS: * inode - Inode pointer * ea_buf - Structure to be populated with ealist and its metadata @@ -1054,7 +1054,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) /* compute required size of list */ for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) { - if (can_list(ea)) + if (can_list(ea)) size += name_size(ea) + 1; } @@ -1069,7 +1069,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) /* Copy attribute names to buffer */ buffer = data; for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) { - if (can_list(ea)) { + if (can_list(ea)) { int namelen = copy_name(buffer, ea); buffer += namelen + 1; } diff --git a/fs/libfs.c b/fs/libfs.c index 3793aaa1457..bd08e0e64a8 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -243,7 +243,7 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den struct inode *inode = old_dentry->d_inode; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - inode->i_nlink++; + inc_nlink(inode); atomic_inc(&inode->i_count); dget(dentry); d_instantiate(dentry, inode); @@ -275,7 +275,7 @@ int simple_unlink(struct inode *dir, struct dentry *dentry) struct inode *inode = dentry->d_inode; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - inode->i_nlink--; + drop_nlink(inode); dput(dentry); return 0; } @@ -285,9 +285,9 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry) if (!simple_empty(dentry)) return -ENOTEMPTY; - dentry->d_inode->i_nlink--; + drop_nlink(dentry->d_inode); simple_unlink(dir, dentry); - dir->i_nlink--; + drop_nlink(dir); return 0; } @@ -303,10 +303,10 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dentry->d_inode) { simple_unlink(new_dir, new_dentry); if (they_are_dirs) - old_dir->i_nlink--; + drop_nlink(old_dir); } else if (they_are_dirs) { - old_dir->i_nlink--; - new_dir->i_nlink++; + drop_nlink(old_dir); + inc_nlink(new_dir); } old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime = diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index f95cc3f3c42..87e1d03e826 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -202,7 +202,7 @@ reclaimer(void *ptr) /* This one ensures that our parent doesn't terminate while the * reclaim is in progress */ lock_kernel(); - lockd_up(); + lockd_up(0); /* note: this cannot fail as lockd is already running */ nlmclnt_prepare_reclaim(host); /* First, reclaim all locks that have been marked. */ diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 271e2165fff..0116729cec5 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -129,11 +129,11 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) nlmclnt_next_cookie(&argp->cookie); argp->state = nsm_local_state; memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh)); - lock->caller = system_utsname.nodename; + lock->caller = utsname()->nodename; lock->oh.data = req->a_owner; lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", (unsigned int)fl->fl_u.nfs_fl.owner->pid, - system_utsname.nodename); + utsname()->nodename); lock->svid = fl->fl_u.nfs_fl.owner->pid; lock->fl.fl_start = fl->fl_start; lock->fl.fl_end = fl->fl_end; diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 5954dcb497e..a816b920d43 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -145,7 +145,7 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) */ sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr)); if (!(p = xdr_encode_string(p, buffer)) - || !(p = xdr_encode_string(p, system_utsname.nodename))) + || !(p = xdr_encode_string(p, utsname()->nodename))) return ERR_PTR(-EIO); *p++ = htonl(argp->prog); *p++ = htonl(argp->vers); diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 9a991b52c64..3cc369e5693 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -31,6 +31,7 @@ #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/sunrpc/svcsock.h> +#include <net/ip.h> #include <linux/lockd/lockd.h> #include <linux/nfs.h> @@ -46,6 +47,7 @@ EXPORT_SYMBOL(nlmsvc_ops); static DEFINE_MUTEX(nlmsvc_mutex); static unsigned int nlmsvc_users; static pid_t nlmsvc_pid; +static struct svc_serv *nlmsvc_serv; int nlmsvc_grace_period; unsigned long nlmsvc_timeout; @@ -96,7 +98,6 @@ static inline void clear_grace_period(void) static void lockd(struct svc_rqst *rqstp) { - struct svc_serv *serv = rqstp->rq_server; int err = 0; unsigned long grace_period_expire; @@ -112,6 +113,7 @@ lockd(struct svc_rqst *rqstp) * Let our maker know we're running. */ nlmsvc_pid = current->pid; + nlmsvc_serv = rqstp->rq_server; complete(&lockd_start_done); daemonize("lockd"); @@ -161,7 +163,7 @@ lockd(struct svc_rqst *rqstp) * Find a socket with data available and call its * recvfrom routine. */ - err = svc_recv(serv, rqstp, timeout); + err = svc_recv(rqstp, timeout); if (err == -EAGAIN || err == -EINTR) continue; if (err < 0) { @@ -174,7 +176,7 @@ lockd(struct svc_rqst *rqstp) dprintk("lockd: request from %08x\n", (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr)); - svc_process(serv, rqstp); + svc_process(rqstp); } @@ -189,6 +191,7 @@ lockd(struct svc_rqst *rqstp) nlmsvc_invalidate_all(); nlm_shutdown_hosts(); nlmsvc_pid = 0; + nlmsvc_serv = NULL; } else printk(KERN_DEBUG "lockd: new process, skipping host shutdown\n"); @@ -205,54 +208,77 @@ lockd(struct svc_rqst *rqstp) module_put_and_exit(0); } + +static int find_socket(struct svc_serv *serv, int proto) +{ + struct svc_sock *svsk; + int found = 0; + list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) + if (svsk->sk_sk->sk_protocol == proto) { + found = 1; + break; + } + return found; +} + +static int make_socks(struct svc_serv *serv, int proto) +{ + /* Make any sockets that are needed but not present. + * If nlm_udpport or nlm_tcpport were set as module + * options, make those sockets unconditionally + */ + static int warned; + int err = 0; + if (proto == IPPROTO_UDP || nlm_udpport) + if (!find_socket(serv, IPPROTO_UDP)) + err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport); + if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport)) + if (!find_socket(serv, IPPROTO_TCP)) + err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport); + if (!err) + warned = 0; + else if (warned++ == 0) + printk(KERN_WARNING + "lockd_up: makesock failed, error=%d\n", err); + return err; +} + /* * Bring up the lockd process if it's not already up. */ int -lockd_up(void) +lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ { - static int warned; struct svc_serv * serv; int error = 0; mutex_lock(&nlmsvc_mutex); /* - * Unconditionally increment the user count ... this is - * the number of clients who _want_ a lockd process. - */ - nlmsvc_users++; - /* * Check whether we're already up and running. */ - if (nlmsvc_pid) + if (nlmsvc_pid) { + if (proto) + error = make_socks(nlmsvc_serv, proto); goto out; + } /* * Sanity check: if there's no pid, * we should be the first user ... */ - if (nlmsvc_users > 1) + if (nlmsvc_users) printk(KERN_WARNING "lockd_up: no pid, %d users??\n", nlmsvc_users); error = -ENOMEM; - serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE); + serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); if (!serv) { printk(KERN_WARNING "lockd_up: create service failed\n"); goto out; } - if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 -#ifdef CONFIG_NFSD_TCP - || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0 -#endif - ) { - if (warned++ == 0) - printk(KERN_WARNING - "lockd_up: makesock failed, error=%d\n", error); + if ((error = make_socks(serv, proto)) < 0) goto destroy_and_out; - } - warned = 0; /* * Create the kernel thread and wait for it to start. @@ -272,6 +298,8 @@ lockd_up(void) destroy_and_out: svc_destroy(serv); out: + if (!error) + nlmsvc_users++; mutex_unlock(&nlmsvc_mutex); return error; } diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index c9d419703cf..93c00ee7189 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -325,7 +325,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) { locks_copy_lock(&call->a_args.lock.fl, &lock->fl); memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); - call->a_args.lock.caller = system_utsname.nodename; + call->a_args.lock.caller = utsname()->nodename; call->a_args.lock.oh.len = lock->oh.len; /* set default data area */ diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 033ea4ac2c3..61c46facf25 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -515,7 +515,7 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) */ #define NLM_void_sz 0 #define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) -#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(system_utsname.nodename)) +#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(utsname()->nodename)) #define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) /* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */ #define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE) diff --git a/fs/locks.c b/fs/locks.c index d7c53392cac..e0b6a80649a 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -314,13 +314,13 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, off_t start, end; switch (l->l_whence) { - case 0: /*SEEK_SET*/ + case SEEK_SET: start = 0; break; - case 1: /*SEEK_CUR*/ + case SEEK_CUR: start = filp->f_pos; break; - case 2: /*SEEK_END*/ + case SEEK_END: start = i_size_read(filp->f_dentry->d_inode); break; default: @@ -364,13 +364,13 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, loff_t start; switch (l->l_whence) { - case 0: /*SEEK_SET*/ + case SEEK_SET: start = 0; break; - case 1: /*SEEK_CUR*/ + case SEEK_CUR: start = filp->f_pos; break; - case 2: /*SEEK_END*/ + case SEEK_END: start = i_size_read(filp->f_dentry->d_inode); break; default: @@ -1514,7 +1514,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg) goto out_unlock; } - error = f_setown(filp, current->pid, 0); + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); out_unlock: unlock_kernel(); return error; diff --git a/fs/minix/file.c b/fs/minix/file.c index 420b32882a1..40eac2e60d2 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -17,8 +17,10 @@ int minix_sync_file(struct file *, struct dentry *, int); const struct file_operations minix_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = minix_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 5b6a4540a05..299bb66e3bd 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -249,7 +249,7 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, minix_set_link(new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/mpage.c b/fs/mpage.c index 1e4598247d0..692a3e578fc 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -693,6 +693,8 @@ out: * the call was made get new I/O started against them. If wbc->sync_mode is * WB_SYNC_ALL then we were called for data integrity and we must wait for * existing IO to complete. + * + * If you fix this you should check generic_writepages() also! */ int mpage_writepages(struct address_space *mapping, diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index d220165d491..b0f01b3b053 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -343,9 +343,9 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - dir->i_nlink--; + drop_nlink(dir); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: @@ -389,7 +389,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode) err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &ts, &sinfo); if (err) goto out_free; - dir->i_nlink++; + inc_nlink(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); @@ -430,7 +430,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: @@ -549,9 +549,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, if (err) goto error_dotdot; } - old_dir->i_nlink--; + drop_nlink(old_dir); if (!new_inode) - new_dir->i_nlink++; + inc_nlink(new_dir); } err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */ @@ -566,10 +566,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, mark_inode_dirty(old_dir); if (new_inode) { + drop_nlink(new_inode); if (is_dir) - new_inode->i_nlink -= 2; - else - new_inode->i_nlink--; + drop_nlink(new_inode); new_inode->i_ctime = ts; } out: diff --git a/fs/namei.c b/fs/namei.c index 2892e68d3a8..28d49b301d5 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1595,6 +1595,24 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) return 0; } +static int open_namei_create(struct nameidata *nd, struct path *path, + int flag, int mode) +{ + int error; + struct dentry *dir = nd->dentry; + + if (!IS_POSIXACL(dir->d_inode)) + mode &= ~current->fs->umask; + error = vfs_create(dir->d_inode, path->dentry, mode, nd); + mutex_unlock(&dir->d_inode->i_mutex); + dput(nd->dentry); + nd->dentry = path->dentry; + if (error) + return error; + /* Don't check for write permission, don't truncate */ + return may_open(nd, 0, flag & ~O_TRUNC); +} + /* * open_namei() * @@ -1676,18 +1694,10 @@ do_last: /* Negative dentry, just create the file */ if (!path.dentry->d_inode) { - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current->fs->umask; - error = vfs_create(dir->d_inode, path.dentry, mode, nd); - mutex_unlock(&dir->d_inode->i_mutex); - dput(nd->dentry); - nd->dentry = path.dentry; + error = open_namei_create(nd, &path, flag, mode); if (error) goto exit; - /* Don't check for write permission, don't truncate */ - acc_mode = 0; - flag &= ~O_TRUNC; - goto ok; + return 0; } /* @@ -1934,30 +1944,32 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) { int error = 0; char * tmp; + struct dentry *dentry; + struct nameidata nd; tmp = getname(pathname); error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - struct dentry *dentry; - struct nameidata nd; + if (IS_ERR(tmp)) + goto out_err; - error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; - dentry = lookup_create(&nd, 1); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - if (!IS_POSIXACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); - path_release(&nd); -out: - putname(tmp); - } + error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); + if (error) + goto out; + dentry = lookup_create(&nd, 1); + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out_unlock; + if (!IS_POSIXACL(nd.dentry->d_inode)) + mode &= ~current->fs->umask; + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); + dput(dentry); +out_unlock: + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); +out: + putname(tmp); +out_err: return error; } @@ -2056,10 +2068,11 @@ static long do_rmdir(int dfd, const char __user *pathname) mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_hash(&nd); error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); - dput(dentry); - } + if (IS_ERR(dentry)) + goto exit2; + error = vfs_rmdir(nd.dentry->d_inode, dentry); + dput(dentry); +exit2: mutex_unlock(&nd.dentry->d_inode->i_mutex); exit1: path_release(&nd); @@ -2199,30 +2212,33 @@ asmlinkage long sys_symlinkat(const char __user *oldname, int error = 0; char * from; char * to; + struct dentry *dentry; + struct nameidata nd; from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); to = getname(newname); error = PTR_ERR(to); - if (!IS_ERR(to)) { - struct dentry *dentry; - struct nameidata nd; + if (IS_ERR(to)) + goto out_putname; - error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); - if (error) - goto out; - dentry = lookup_create(&nd, 0); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); - path_release(&nd); + error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); + if (error) + goto out; + dentry = lookup_create(&nd, 0); + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out_unlock; + + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); + dput(dentry); +out_unlock: + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: - putname(to); - } + putname(to); +out_putname: putname(from); return error; } @@ -2308,10 +2324,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, goto out_release; new_dentry = lookup_create(&nd, 0); error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); - dput(new_dentry); - } + if (IS_ERR(new_dentry)) + goto out_unlock; + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); + dput(new_dentry); +out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); out_release: path_release(&nd); diff --git a/fs/namespace.c b/fs/namespace.c index 6ede3a539ed..55442a6cf22 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -24,12 +24,11 @@ #include <linux/namei.h> #include <linux/security.h> #include <linux/mount.h> +#include <linux/ramfs.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include "pnode.h" -extern int __init init_rootfs(void); - /* spinlock for vfsmount related operations, inplace of dcache_lock */ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); @@ -134,7 +133,7 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry) static inline int check_mnt(struct vfsmount *mnt) { - return mnt->mnt_namespace == current->namespace; + return mnt->mnt_namespace == current->nsproxy->namespace; } static void touch_namespace(struct namespace *ns) @@ -831,7 +830,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, if (parent_nd) { detach_mnt(source_mnt, parent_nd); attach_mnt(source_mnt, nd); - touch_namespace(current->namespace); + touch_namespace(current->nsproxy->namespace); } else { mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); commit_tree(source_mnt); @@ -1442,7 +1441,7 @@ dput_out: */ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) { - struct namespace *namespace = tsk->namespace; + struct namespace *namespace = tsk->nsproxy->namespace; struct namespace *new_ns; struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; struct vfsmount *p, *q; @@ -1509,7 +1508,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) int copy_namespace(int flags, struct task_struct *tsk) { - struct namespace *namespace = tsk->namespace; + struct namespace *namespace = tsk->nsproxy->namespace; struct namespace *new_ns; int err = 0; @@ -1532,7 +1531,7 @@ int copy_namespace(int flags, struct task_struct *tsk) goto out; } - tsk->namespace = new_ns; + tsk->nsproxy->namespace = new_ns; out: put_namespace(namespace); @@ -1755,7 +1754,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root, detach_mnt(user_nd.mnt, &root_parent); attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */ attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */ - touch_namespace(current->namespace); + touch_namespace(current->nsproxy->namespace); spin_unlock(&vfsmount_lock); chroot_fs_refs(&user_nd, &new_nd); security_sb_post_pivotroot(&user_nd, &new_nd); @@ -1781,7 +1780,6 @@ static void __init init_mount_tree(void) { struct vfsmount *mnt; struct namespace *namespace; - struct task_struct *g, *p; mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); if (IS_ERR(mnt)) @@ -1797,13 +1795,8 @@ static void __init init_mount_tree(void) namespace->root = mnt; mnt->mnt_namespace = namespace; - init_task.namespace = namespace; - read_lock(&tasklist_lock); - do_each_thread(g, p) { - get_namespace(namespace); - p->namespace = namespace; - } while_each_thread(g, p); - read_unlock(&tasklist_lock); + init_task.nsproxy->namespace = namespace; + get_namespace(namespace); set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root); set_fs_root(current->fs, namespace->root, namespace->root->mnt_root); diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index b4ee89250e9..458b3b78519 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -53,6 +53,9 @@ const struct file_operations ncp_dir_operations = .read = generic_read_dir, .readdir = ncp_readdir, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif }; struct inode_operations ncp_dir_inode_operations = diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index e6b7c67cf05..df37524b85d 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -289,6 +289,9 @@ const struct file_operations ncp_file_operations = .read = ncp_file_read, .write = ncp_file_write, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif .mmap = ncp_mmap, .release = ncp_release, .fsync = ncp_fsync, diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 42039fe0653..a89ac84a824 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -7,19 +7,21 @@ * */ - -#include <asm/uaccess.h> #include <linux/capability.h> +#include <linux/compat.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/ioctl.h> #include <linux/time.h> #include <linux/mm.h> #include <linux/highuid.h> +#include <linux/smp_lock.h> #include <linux/vmalloc.h> #include <linux/ncp_fs.h> +#include <asm/uaccess.h> + #include "ncplib_kernel.h" /* maximum limit for ncp_objectname_ioctl */ @@ -89,6 +91,82 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file, return 0; } +#ifdef CONFIG_COMPAT +struct compat_ncp_objectname_ioctl +{ + s32 auth_type; + u32 object_name_len; + compat_caddr_t object_name; /* an userspace data, in most cases user name */ +}; + +struct compat_ncp_fs_info_v2 { + s32 version; + u32 mounted_uid; + u32 connection; + u32 buffer_size; + + u32 volume_number; + u32 directory_id; + + u32 dummy1; + u32 dummy2; + u32 dummy3; +}; + +struct compat_ncp_ioctl_request { + u32 function; + u32 size; + compat_caddr_t data; +}; + +struct compat_ncp_privatedata_ioctl +{ + u32 len; + compat_caddr_t data; /* ~1000 for NDS */ +}; + +#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct compat_ncp_fs_info_v2) +#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct compat_ncp_ioctl_request) +#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct compat_ncp_objectname_ioctl) +#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct compat_ncp_objectname_ioctl) +#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct compat_ncp_privatedata_ioctl) +#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl) + +static int +ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file, + struct compat_ncp_fs_info_v2 __user * arg) +{ + struct inode *inode = file->f_dentry->d_inode; + struct compat_ncp_fs_info_v2 info2; + + if ((file_permission(file, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (copy_from_user(&info2, arg, sizeof(info2))) + return -EFAULT; + + if (info2.version != NCP_GET_FS_INFO_VERSION_V2) { + DPRINTK("info.version invalid: %d\n", info2.version); + return -EINVAL; + } + info2.mounted_uid = server->m.mounted_uid; + info2.connection = server->connection; + info2.buffer_size = server->buffer_size; + info2.volume_number = NCP_FINFO(inode)->volNumber; + info2.directory_id = NCP_FINFO(inode)->DosDirNum; + info2.dummy1 = info2.dummy2 = info2.dummy3 = 0; + + if (copy_to_user(arg, &info2, sizeof(info2))) + return -EFAULT; + return 0; +} +#endif + +#define NCP_IOC_GETMOUNTUID16 _IOW('n', 2, u16) +#define NCP_IOC_GETMOUNTUID32 _IOW('n', 2, u32) +#define NCP_IOC_GETMOUNTUID64 _IOW('n', 2, u64) + #ifdef CONFIG_NCPFS_NLS /* Here we are select the iocharset and the codepage for NLS. * Thanks Petr Vandrovec for idea and many hints. @@ -192,12 +270,24 @@ int ncp_ioctl(struct inode *inode, struct file *filp, void __user *argp = (void __user *)arg; switch (cmd) { +#ifdef CONFIG_COMPAT + case NCP_IOC_NCPREQUEST_32: +#endif case NCP_IOC_NCPREQUEST: - if ((file_permission(filp, MAY_WRITE) != 0) && (current->uid != server->m.mounted_uid)) { return -EACCES; } +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_NCPREQUEST_32) { + struct compat_ncp_ioctl_request request32; + if (copy_from_user(&request32, argp, sizeof(request32))) + return -EFAULT; + request.function = request32.function; + request.size = request32.size; + request.data = compat_ptr(request32.data); + } else +#endif if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; @@ -254,19 +344,35 @@ int ncp_ioctl(struct inode *inode, struct file *filp, case NCP_IOC_GET_FS_INFO_V2: return ncp_get_fs_info_v2(server, filp, argp); - case NCP_IOC_GETMOUNTUID2: - { - unsigned long tmp = server->m.mounted_uid; - - if ((file_permission(filp, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) - { - return -EACCES; - } - if (put_user(tmp, (unsigned long __user *)argp)) +#ifdef CONFIG_COMPAT + case NCP_IOC_GET_FS_INFO_V2_32: + return ncp_get_compat_fs_info_v2(server, filp, argp); +#endif + /* we have too many combinations of CONFIG_COMPAT, + * CONFIG_64BIT and CONFIG_UID16, so just handle + * any of the possible ioctls */ + case NCP_IOC_GETMOUNTUID16: + case NCP_IOC_GETMOUNTUID32: + case NCP_IOC_GETMOUNTUID64: + if ((file_permission(filp, MAY_READ) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (cmd == NCP_IOC_GETMOUNTUID16) { + u16 uid; + SET_UID(uid, server->m.mounted_uid); + if (put_user(uid, (u16 __user *)argp)) + return -EFAULT; + } else if (cmd == NCP_IOC_GETMOUNTUID32) { + if (put_user(server->m.mounted_uid, + (u32 __user *)argp)) + return -EFAULT; + } else { + if (put_user(server->m.mounted_uid, + (u64 __user *)argp)) return -EFAULT; - return 0; } + return 0; case NCP_IOC_GETROOT: { @@ -476,6 +582,32 @@ outrel: } #endif /* CONFIG_NCPFS_IOCTL_LOCKING */ +#ifdef CONFIG_COMPAT + case NCP_IOC_GETOBJECTNAME_32: + if (current->uid != server->m.mounted_uid) { + return -EACCES; + } + { + struct compat_ncp_objectname_ioctl user; + size_t outl; + + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + user.auth_type = server->auth.auth_type; + outl = user.object_name_len; + user.object_name_len = server->auth.object_name_len; + if (outl > user.object_name_len) + outl = user.object_name_len; + if (outl) { + if (copy_to_user(compat_ptr(user.object_name), + server->auth.object_name, + outl)) return -EFAULT; + } + if (copy_to_user(argp, &user, sizeof(user))) + return -EFAULT; + return 0; + } +#endif case NCP_IOC_GETOBJECTNAME: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -500,6 +632,9 @@ outrel: return -EFAULT; return 0; } +#ifdef CONFIG_COMPAT + case NCP_IOC_SETOBJECTNAME_32: +#endif case NCP_IOC_SETOBJECTNAME: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -512,8 +647,19 @@ outrel: void* oldprivate; size_t oldprivatelen; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_SETOBJECTNAME_32) { + struct compat_ncp_objectname_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.auth_type = user32.auth_type; + user.object_name_len = user32.object_name_len; + user.object_name = compat_ptr(user32.object_name); + } else +#endif if (copy_from_user(&user, argp, sizeof(user))) return -EFAULT; + if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN) return -ENOMEM; if (user.object_name_len) { @@ -544,6 +690,9 @@ outrel: kfree(oldname); return 0; } +#ifdef CONFIG_COMPAT + case NCP_IOC_GETPRIVATEDATA_32: +#endif case NCP_IOC_GETPRIVATEDATA: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -552,8 +701,18 @@ outrel: struct ncp_privatedata_ioctl user; size_t outl; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_GETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.len = user32.len; + user.data = compat_ptr(user32.data); + } else +#endif if (copy_from_user(&user, argp, sizeof(user))) return -EFAULT; + outl = user.len; user.len = server->priv.len; if (outl > user.len) outl = user.len; @@ -562,10 +721,23 @@ outrel: server->priv.data, outl)) return -EFAULT; } +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_GETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + user32.len = user.len; + user32.data = (unsigned long) user.data; + if (copy_to_user(&user32, argp, sizeof(user32))) + return -EFAULT; + } else +#endif if (copy_to_user(argp, &user, sizeof(user))) return -EFAULT; + return 0; } +#ifdef CONFIG_COMPAT + case NCP_IOC_SETPRIVATEDATA_32: +#endif case NCP_IOC_SETPRIVATEDATA: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -576,8 +748,18 @@ outrel: void* old; size_t oldlen; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_SETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.len = user32.len; + user.data = compat_ptr(user32.data); + } else +#endif if (copy_from_user(&user, argp, sizeof(user))) return -EFAULT; + if (user.len > NCP_PRIVATE_DATA_MAX_LEN) return -ENOMEM; if (user.len) { @@ -636,20 +818,19 @@ outrel: } } -/* #ifdef CONFIG_UID16 */ - /* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2, - so we have this out of switch */ - if (cmd == NCP_IOC_GETMOUNTUID) { - __kernel_uid_t uid = 0; - if ((file_permission(filp, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) { - return -EACCES; - } - SET_UID(uid, server->m.mounted_uid); - if (put_user(uid, (__kernel_uid_t __user *)argp)) - return -EFAULT; - return 0; - } -/* #endif */ return -EINVAL; } + +#ifdef CONFIG_COMPAT +long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + lock_kernel(); + arg = (unsigned long) compat_ptr(arg); + ret = ncp_ioctl(inode, file, cmd, arg); + unlock_kernel(); + return ret; +} +#endif diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index a3ee11364db..7933e2e99db 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -58,7 +58,6 @@ module_param_call(callback_tcpport, param_set_port, param_get_int, */ static void nfs_callback_svc(struct svc_rqst *rqstp) { - struct svc_serv *serv = rqstp->rq_server; int err; __module_get(THIS_MODULE); @@ -80,7 +79,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) /* * Listen for a request on the socket */ - err = svc_recv(serv, rqstp, MAX_SCHEDULE_TIMEOUT); + err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT); if (err == -EAGAIN || err == -EINTR) continue; if (err < 0) { @@ -91,7 +90,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) } dprintk("%s: request from %u.%u.%u.%u\n", __FUNCTION__, NIPQUAD(rqstp->rq_addr.sin_addr.s_addr)); - svc_process(serv, rqstp); + svc_process(rqstp); } svc_exit_thread(rqstp); @@ -116,7 +115,7 @@ int nfs_callback_up(void) goto out; init_completion(&nfs_callback_info.started); init_completion(&nfs_callback_info.stopped); - serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE); + serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); ret = -ENOMEM; if (!serv) goto out_err; diff --git a/fs/nfs/client.c b/fs/nfs/client.c index ec1938d4b81..8106f3b29e4 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -460,7 +460,8 @@ static int nfs_start_lockd(struct nfs_server *server) goto out; if (server->flags & NFS_MOUNT_NONLM) goto out; - error = lockd_up(); + error = lockd_up((server->flags & NFS_MOUNT_TCP) ? + IPPROTO_TCP : IPPROTO_UDP); if (error < 0) server->flags |= NFS_MOUNT_NONLM; else diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7432f1a43f3..481f8892a91 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -843,7 +843,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) nfs_inode_return_delegation(inode); if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { lock_kernel(); - inode->i_nlink--; + drop_nlink(inode); nfs_complete_unlink(dentry); unlock_kernel(); } @@ -1286,7 +1286,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); /* Ensure the VFS deletes this inode */ if (error == 0 && dentry->d_inode != NULL) - dentry->d_inode->i_nlink = 0; + clear_nlink(dentry->d_inode); nfs_end_data_update(dir); unlock_kernel(); @@ -1401,7 +1401,7 @@ static int nfs_safe_remove(struct dentry *dentry) error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); /* The VFS may want to delete this inode */ if (error == 0) - inode->i_nlink--; + drop_nlink(inode); nfs_mark_for_revalidate(inode); nfs_end_data_update(inode); } else @@ -1639,7 +1639,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; } } else - new_inode->i_nlink--; + drop_nlink(new_inode); go_ahead: /* diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 377839bed17..9f7f8b9ea1e 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -707,8 +707,8 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz /** * nfs_file_direct_read - file direct read operation for NFS files * @iocb: target I/O control block - * @buf: user's buffer into which to read data - * @count: number of bytes to read + * @iov: vector of user buffers into which to read data + * @nr_segs: size of iov vector * @pos: byte offset in file where reading starts * * We use this function for direct reads instead of calling @@ -725,17 +725,24 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz * client must read the updated atime from the server back into its * cache. */ -ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) +ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { ssize_t retval = -EINVAL; struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; + /* XXX: temporary */ + const char __user *buf = iov[0].iov_base; + size_t count = iov[0].iov_len; dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", file->f_dentry->d_parent->d_name.name, file->f_dentry->d_name.name, (unsigned long) count, (long long) pos); + if (nr_segs != 1) + return -EINVAL; + if (count < 0) goto out; retval = -EFAULT; @@ -760,8 +767,8 @@ out: /** * nfs_file_direct_write - file direct write operation for NFS files * @iocb: target I/O control block - * @buf: user's buffer from which to write data - * @count: number of bytes to write + * @iov: vector of user buffers from which to write data + * @nr_segs: size of iov vector * @pos: byte offset in file where writing starts * * We use this function for direct writes instead of calling @@ -782,17 +789,24 @@ out: * Note that O_APPEND is not supported for NFS direct writes, as there * is no atomic O_APPEND write facility in the NFS protocol. */ -ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { ssize_t retval; struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; + /* XXX: temporary */ + const char __user *buf = iov[0].iov_base; + size_t count = iov[0].iov_len; dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", file->f_dentry->d_parent->d_name.name, file->f_dentry->d_name.name, (unsigned long) count, (long long) pos); + if (nr_segs != 1) + return -EINVAL; + retval = generic_write_checks(file, &pos, &count, 0); if (retval) goto out; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index be997d64912..cc93865cea9 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -41,8 +41,10 @@ static int nfs_file_release(struct inode *, struct file *); static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); static int nfs_file_mmap(struct file *, struct vm_area_struct *); static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); -static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); -static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); +static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); static int nfs_file_flush(struct file *, fl_owner_t id); static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); static int nfs_check_flags(int flags); @@ -53,8 +55,8 @@ const struct file_operations nfs_file_operations = { .llseek = nfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = nfs_file_read, - .aio_write = nfs_file_write, + .aio_read = nfs_file_read, + .aio_write = nfs_file_write, .mmap = nfs_file_mmap, .open = nfs_file_open, .flush = nfs_file_flush, @@ -196,15 +198,17 @@ nfs_file_flush(struct file *file, fl_owner_t id) } static ssize_t -nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) +nfs_file_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct dentry * dentry = iocb->ki_filp->f_dentry; struct inode * inode = dentry->d_inode; ssize_t result; + size_t count = iov_length(iov, nr_segs); #ifdef CONFIG_NFS_DIRECTIO if (iocb->ki_filp->f_flags & O_DIRECT) - return nfs_file_direct_read(iocb, buf, count, pos); + return nfs_file_direct_read(iocb, iov, nr_segs, pos); #endif dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", @@ -214,7 +218,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); if (!result) - result = generic_file_aio_read(iocb, buf, count, pos); + result = generic_file_aio_read(iocb, iov, nr_segs, pos); return result; } @@ -336,24 +340,22 @@ const struct address_space_operations nfs_file_aops = { #endif }; -/* - * Write to a file (through the page cache). - */ -static ssize_t -nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct dentry * dentry = iocb->ki_filp->f_dentry; struct inode * inode = dentry->d_inode; ssize_t result; + size_t count = iov_length(iov, nr_segs); #ifdef CONFIG_NFS_DIRECTIO if (iocb->ki_filp->f_flags & O_DIRECT) - return nfs_file_direct_write(iocb, buf, count, pos); + return nfs_file_direct_write(iocb, iov, nr_segs, pos); #endif - dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n", + dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino, (unsigned long) count, (unsigned long) pos); + inode->i_ino, (unsigned long) count, (long long) pos); result = -EBUSY; if (IS_SWAPFILE(inode)) @@ -372,7 +374,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t goto out; nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); - result = generic_file_aio_write(iocb, buf, count, pos); + result = generic_file_aio_write(iocb, iov, nr_segs, pos); out: return result; diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index c0a754ecdee..1d656a64519 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -312,7 +312,7 @@ static int __init root_nfs_name(char *name) /* Override them by options set on kernel command-line */ root_nfs_parse(name, buf); - cp = system_utsname.nodename; + cp = utsname()->nodename; if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) { printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n"); return -1; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b674462793d..f6675d2c386 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -51,7 +51,6 @@ #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/file.h> -#include <linux/mpage.h> #include <linux/writeback.h> #include <linux/sunrpc/clnt.h> diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 01bc68c628a..cfe141e5d75 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -370,7 +370,7 @@ static int check_export(struct inode *inode, int flags) */ if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) && !(flags & NFSEXP_FSID)) { - dprintk("exp_export: export of non-dev fs without fsid"); + dprintk("exp_export: export of non-dev fs without fsid\n"); return -EINVAL; } if (!inode->i_sb->s_export_op) { @@ -1078,6 +1078,7 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, /* Iterator */ static void *e_start(struct seq_file *m, loff_t *pos) + __acquires(svc_export_cache.hash_lock) { loff_t n = *pos; unsigned hash, export; @@ -1086,7 +1087,7 @@ static void *e_start(struct seq_file *m, loff_t *pos) exp_readlock(); read_lock(&svc_export_cache.hash_lock); if (!n--) - return (void *)1; + return SEQ_START_TOKEN; hash = n >> 32; export = n & ((1LL<<32) - 1); @@ -1110,7 +1111,7 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos) struct cache_head *ch = p; int hash = (*pos >> 32); - if (p == (void *)1) + if (p == SEQ_START_TOKEN) hash = 0; else if (ch->next == NULL) { hash++; @@ -1131,6 +1132,7 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos) } static void e_stop(struct seq_file *m, void *p) + __releases(svc_export_cache.hash_lock) { read_unlock(&svc_export_cache.hash_lock); exp_readunlock(); @@ -1178,15 +1180,13 @@ static int e_show(struct seq_file *m, void *p) { struct cache_head *cp = p; struct svc_export *exp = container_of(cp, struct svc_export, h); - svc_client *clp; - if (p == (void *)1) { + if (p == SEQ_START_TOKEN) { seq_puts(m, "# Version 1.1\n"); seq_puts(m, "# Path Client(Flags) # IPs\n"); return 0; } - clp = exp->ex_client; cache_get(&exp->h); if (cache_check(&svc_export_cache, &exp->h, NULL)) return 0; diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 8583d99ee74..f6ca9fb3fc6 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -131,7 +131,7 @@ xdr_error: \ #define READ_BUF(nbytes) do { \ p = xdr_inline_decode(xdr, nbytes); \ if (!p) { \ - dprintk("NFSD: %s: reply buffer overflowed in line %d.", \ + dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \ __FUNCTION__, __LINE__); \ return -EIO; \ } \ diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index ee4eff27aed..15ded7a30a7 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -600,7 +600,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); nfs4_unlock_state(); if (status) { - dprintk("NFSD: nfsd4_setattr: couldn't process stateid!"); + dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); return status; } } diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index e35d7e52fde..1cbd2e4ee12 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -184,7 +184,7 @@ struct dentry_list_arg { static int nfsd4_build_dentrylist(void *arg, const char *name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct dentry_list_arg *dla = arg; struct list_head *dentries = &dla->dentries; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 7046ac9cf97..5c6a477c20e 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -23,10 +23,14 @@ #include <linux/pagemap.h> #include <linux/init.h> #include <linux/string.h> +#include <linux/smp_lock.h> +#include <linux/ctype.h> #include <linux/nfs.h> #include <linux/nfsd_idmap.h> +#include <linux/lockd/bind.h> #include <linux/sunrpc/svc.h> +#include <linux/sunrpc/svcsock.h> #include <linux/nfsd/nfsd.h> #include <linux/nfsd/cache.h> #include <linux/nfsd/xdr.h> @@ -35,8 +39,6 @@ #include <asm/uaccess.h> -unsigned int nfsd_versbits = ~0; - /* * We have a single directory with 9 nodes in it. */ @@ -52,7 +54,9 @@ enum { NFSD_List, NFSD_Fh, NFSD_Threads, + NFSD_Pool_Threads, NFSD_Versions, + NFSD_Ports, /* * The below MUST come last. Otherwise we leave a hole in nfsd_files[] * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops @@ -75,7 +79,9 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size); static ssize_t write_getfs(struct file *file, char *buf, size_t size); static ssize_t write_filehandle(struct file *file, char *buf, size_t size); static ssize_t write_threads(struct file *file, char *buf, size_t size); +static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); static ssize_t write_versions(struct file *file, char *buf, size_t size); +static ssize_t write_ports(struct file *file, char *buf, size_t size); #ifdef CONFIG_NFSD_V4 static ssize_t write_leasetime(struct file *file, char *buf, size_t size); static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); @@ -91,7 +97,9 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [NFSD_Getfs] = write_getfs, [NFSD_Fh] = write_filehandle, [NFSD_Threads] = write_threads, + [NFSD_Pool_Threads] = write_pool_threads, [NFSD_Versions] = write_versions, + [NFSD_Ports] = write_ports, #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = write_leasetime, [NFSD_RecoveryDir] = write_recoverydir, @@ -358,6 +366,72 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) return strlen(buf); } +extern int nfsd_nrpools(void); +extern int nfsd_get_nrthreads(int n, int *); +extern int nfsd_set_nrthreads(int n, int *); + +static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) +{ + /* if size > 0, look for an array of number of threads per node + * and apply them then write out number of threads per node as reply + */ + char *mesg = buf; + int i; + int rv; + int len; + int npools = nfsd_nrpools(); + int *nthreads; + + if (npools == 0) { + /* + * NFS is shut down. The admin can start it by + * writing to the threads file but NOT the pool_threads + * file, sorry. Report zero threads. + */ + strcpy(buf, "0\n"); + return strlen(buf); + } + + nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); + if (nthreads == NULL) + return -ENOMEM; + + if (size > 0) { + for (i = 0; i < npools; i++) { + rv = get_int(&mesg, &nthreads[i]); + if (rv == -ENOENT) + break; /* fewer numbers than pools */ + if (rv) + goto out_free; /* syntax error */ + rv = -EINVAL; + if (nthreads[i] < 0) + goto out_free; + } + rv = nfsd_set_nrthreads(i, nthreads); + if (rv) + goto out_free; + } + + rv = nfsd_get_nrthreads(npools, nthreads); + if (rv) + goto out_free; + + mesg = buf; + size = SIMPLE_TRANSACTION_LIMIT; + for (i = 0; i < npools && size > 0; i++) { + snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' ')); + len = strlen(mesg); + size -= len; + mesg += len; + } + + return (mesg-buf); + +out_free: + kfree(nthreads); + return rv; +} + static ssize_t write_versions(struct file *file, char *buf, size_t size) { /* @@ -372,6 +446,10 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size) if (size>0) { if (nfsd_serv) + /* Cannot change versions without updating + * nfsd_serv->sv_xdrsize, and reallocing + * rq_argp and rq_resp + */ return -EBUSY; if (buf[size-1] != '\n') return -EINVAL; @@ -390,10 +468,7 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size) case 2: case 3: case 4: - if (sign != '-') - NFSCTL_VERSET(nfsd_versbits, num); - else - NFSCTL_VERUNSET(nfsd_versbits, num); + nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET); break; default: return -EINVAL; @@ -404,16 +479,15 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size) /* If all get turned off, turn them back on, as * having no versions is BAD */ - if ((nfsd_versbits & NFSCTL_VERALL)==0) - nfsd_versbits = NFSCTL_VERALL; + nfsd_reset_versions(); } /* Now write current state into reply buffer */ len = 0; sep = ""; for (num=2 ; num <= 4 ; num++) - if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) { + if (nfsd_vers(num, NFSD_AVAIL)) { len += sprintf(buf+len, "%s%c%d", sep, - NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-', + nfsd_vers(num, NFSD_TEST)?'+':'-', num); sep = " "; } @@ -421,6 +495,62 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size) return len; } +static ssize_t write_ports(struct file *file, char *buf, size_t size) +{ + if (size == 0) { + int len = 0; + lock_kernel(); + if (nfsd_serv) + len = svc_sock_names(buf, nfsd_serv, NULL); + unlock_kernel(); + return len; + } + /* Either a single 'fd' number is written, in which + * case it must be for a socket of a supported family/protocol, + * and we use it as an nfsd socket, or + * A '-' followed by the 'name' of a socket in which case + * we close the socket. + */ + if (isdigit(buf[0])) { + char *mesg = buf; + int fd; + int err; + err = get_int(&mesg, &fd); + if (err) + return -EINVAL; + if (fd < 0) + return -EINVAL; + err = nfsd_create_serv(); + if (!err) { + int proto = 0; + err = lockd_up(proto); + if (!err) { + err = svc_addsock(nfsd_serv, fd, buf, &proto); + if (err) + lockd_down(); + } + /* Decrease the count, but don't shutdown the + * the service + */ + nfsd_serv->sv_nrthreads--; + } + return err; + } + if (buf[0] == '-') { + char *toclose = kstrdup(buf+1, GFP_KERNEL); + int len = 0; + if (!toclose) + return -ENOMEM; + lock_kernel(); + if (nfsd_serv) + len = svc_sock_names(buf, nfsd_serv, toclose); + unlock_kernel(); + kfree(toclose); + return len; + } + return -EINVAL; +} + #ifdef CONFIG_NFSD_V4 extern time_t nfs4_leasetime(void); @@ -483,7 +613,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, + [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, + [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index ec1decf29ba..19443056ec3 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -57,12 +57,6 @@ static atomic_t nfsd_busy; static unsigned long nfsd_last_call; static DEFINE_SPINLOCK(nfsd_call_lock); -struct nfsd_list { - struct list_head list; - struct task_struct *task; -}; -static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); - #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) static struct svc_stat nfsd_acl_svcstats; static struct svc_version * nfsd_acl_version[] = { @@ -117,6 +111,32 @@ struct svc_program nfsd_program = { }; +int nfsd_vers(int vers, enum vers_op change) +{ + if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS) + return -1; + switch(change) { + case NFSD_SET: + nfsd_versions[vers] = nfsd_version[vers]; + break; +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + if (vers < NFSD_ACL_NRVERS) + nfsd_acl_version[vers] = nfsd_acl_version[vers]; +#endif + case NFSD_CLEAR: + nfsd_versions[vers] = NULL; +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + if (vers < NFSD_ACL_NRVERS) + nfsd_acl_version[vers] = NULL; +#endif + break; + case NFSD_TEST: + return nfsd_versions[vers] != NULL; + case NFSD_AVAIL: + return nfsd_version[vers] != NULL; + } + return 0; +} /* * Maximum number of nfsd processes */ @@ -130,16 +150,175 @@ int nfsd_nrthreads(void) return nfsd_serv->sv_nrthreads; } +static int killsig; /* signal that was used to kill last nfsd */ +static void nfsd_last_thread(struct svc_serv *serv) +{ + /* When last nfsd thread exits we need to do some clean-up */ + struct svc_sock *svsk; + list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) + lockd_down(); + nfsd_serv = NULL; + nfsd_racache_shutdown(); + nfs4_state_shutdown(); + + printk(KERN_WARNING "nfsd: last server has exited\n"); + if (killsig != SIG_NOCLEAN) { + printk(KERN_WARNING "nfsd: unexporting all filesystems\n"); + nfsd_export_flush(); + } +} + +void nfsd_reset_versions(void) +{ + int found_one = 0; + int i; + + for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { + if (nfsd_program.pg_vers[i]) + found_one = 1; + } + + if (!found_one) { + for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) + nfsd_program.pg_vers[i] = nfsd_version[i]; +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) + nfsd_acl_program.pg_vers[i] = + nfsd_acl_version[i]; +#endif + } +} + +int nfsd_create_serv(void) +{ + int err = 0; + lock_kernel(); + if (nfsd_serv) { + svc_get(nfsd_serv); + unlock_kernel(); + return 0; + } + + atomic_set(&nfsd_busy, 0); + nfsd_serv = svc_create_pooled(&nfsd_program, NFSD_BUFSIZE, + nfsd_last_thread, + nfsd, SIG_NOCLEAN, THIS_MODULE); + if (nfsd_serv == NULL) + err = -ENOMEM; + unlock_kernel(); + do_gettimeofday(&nfssvc_boot); /* record boot time */ + return err; +} + +static int nfsd_init_socks(int port) +{ + int error; + if (!list_empty(&nfsd_serv->sv_permsocks)) + return 0; + + error = lockd_up(IPPROTO_UDP); + if (error >= 0) { + error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); + if (error < 0) + lockd_down(); + } + if (error < 0) + return error; + +#ifdef CONFIG_NFSD_TCP + error = lockd_up(IPPROTO_TCP); + if (error >= 0) { + error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); + if (error < 0) + lockd_down(); + } + if (error < 0) + return error; +#endif + return 0; +} + +int nfsd_nrpools(void) +{ + if (nfsd_serv == NULL) + return 0; + else + return nfsd_serv->sv_nrpools; +} + +int nfsd_get_nrthreads(int n, int *nthreads) +{ + int i = 0; + + if (nfsd_serv != NULL) { + for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++) + nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads; + } + + return 0; +} + +int nfsd_set_nrthreads(int n, int *nthreads) +{ + int i = 0; + int tot = 0; + int err = 0; + + if (nfsd_serv == NULL || n <= 0) + return 0; + + if (n > nfsd_serv->sv_nrpools) + n = nfsd_serv->sv_nrpools; + + /* enforce a global maximum number of threads */ + tot = 0; + for (i = 0; i < n; i++) { + if (nthreads[i] > NFSD_MAXSERVS) + nthreads[i] = NFSD_MAXSERVS; + tot += nthreads[i]; + } + if (tot > NFSD_MAXSERVS) { + /* total too large: scale down requested numbers */ + for (i = 0; i < n && tot > 0; i++) { + int new = nthreads[i] * NFSD_MAXSERVS / tot; + tot -= (nthreads[i] - new); + nthreads[i] = new; + } + for (i = 0; i < n && tot > 0; i++) { + nthreads[i]--; + tot--; + } + } + + /* + * There must always be a thread in pool 0; the admin + * can't shut down NFS completely using pool_threads. + */ + if (nthreads[0] == 0) + nthreads[0] = 1; + + /* apply the new numbers */ + lock_kernel(); + svc_get(nfsd_serv); + for (i = 0; i < n; i++) { + err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i], + nthreads[i]); + if (err) + break; + } + svc_destroy(nfsd_serv); + unlock_kernel(); + + return err; +} + int nfsd_svc(unsigned short port, int nrservs) { int error; - int none_left, found_one, i; - struct list_head *victim; lock_kernel(); - dprintk("nfsd: creating service: vers 0x%x\n", - nfsd_versbits); + dprintk("nfsd: creating service\n"); error = -EINVAL; if (nrservs <= 0) nrservs = 0; @@ -153,91 +332,20 @@ nfsd_svc(unsigned short port, int nrservs) error = nfs4_state_start(); if (error<0) goto out; - if (!nfsd_serv) { - /* - * Use the nfsd_ctlbits to define which - * versions that will be advertised. - * If nfsd_ctlbits doesn't list any version, - * export them all. - */ - found_one = 0; - - for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { - if (NFSCTL_VERISSET(nfsd_versbits, i)) { - nfsd_program.pg_vers[i] = nfsd_version[i]; - found_one = 1; - } else - nfsd_program.pg_vers[i] = NULL; - } - if (!found_one) { - for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) - nfsd_program.pg_vers[i] = nfsd_version[i]; - } + nfsd_reset_versions(); + error = nfsd_create_serv(); -#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) - found_one = 0; - - for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) { - if (NFSCTL_VERISSET(nfsd_versbits, i)) { - nfsd_acl_program.pg_vers[i] = - nfsd_acl_version[i]; - found_one = 1; - } else - nfsd_acl_program.pg_vers[i] = NULL; - } - - if (!found_one) { - for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) - nfsd_acl_program.pg_vers[i] = - nfsd_acl_version[i]; - } -#endif - - atomic_set(&nfsd_busy, 0); - error = -ENOMEM; - nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); - if (nfsd_serv == NULL) - goto out; - error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); - if (error < 0) - goto failure; + if (error) + goto out; + error = nfsd_init_socks(port); + if (error) + goto failure; -#ifdef CONFIG_NFSD_TCP - error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); - if (error < 0) - goto failure; -#endif - do_gettimeofday(&nfssvc_boot); /* record boot time */ - } else - nfsd_serv->sv_nrthreads++; - nrservs -= (nfsd_serv->sv_nrthreads-1); - while (nrservs > 0) { - nrservs--; - __module_get(THIS_MODULE); - error = svc_create_thread(nfsd, nfsd_serv); - if (error < 0) { - module_put(THIS_MODULE); - break; - } - } - victim = nfsd_list.next; - while (nrservs < 0 && victim != &nfsd_list) { - struct nfsd_list *nl = - list_entry(victim,struct nfsd_list, list); - victim = victim->next; - send_sig(SIG_NOCLEAN, nl->task, 1); - nrservs++; - } + error = svc_set_num_threads(nfsd_serv, NULL, nrservs); failure: - none_left = (nfsd_serv->sv_nrthreads == 1); svc_destroy(nfsd_serv); /* Release server */ - if (none_left) { - nfsd_serv = NULL; - nfsd_racache_shutdown(); - nfs4_state_shutdown(); - } out: unlock_kernel(); return error; @@ -270,10 +378,8 @@ update_thread_usage(int busy_threads) static void nfsd(struct svc_rqst *rqstp) { - struct svc_serv *serv = rqstp->rq_server; struct fs_struct *fsp; int err; - struct nfsd_list me; sigset_t shutdown_mask, allowed_mask; /* Lock module and set up kernel thread */ @@ -297,10 +403,7 @@ nfsd(struct svc_rqst *rqstp) nfsdstats.th_cnt++; - lockd_up(); /* start lockd */ - - me.task = current; - list_add(&me.list, &nfsd_list); + rqstp->rq_task = current; unlock_kernel(); @@ -322,8 +425,7 @@ nfsd(struct svc_rqst *rqstp) * Find a socket with data available and call its * recvfrom routine. */ - while ((err = svc_recv(serv, rqstp, - 60*60*HZ)) == -EAGAIN) + while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN) ; if (err < 0) break; @@ -336,7 +438,7 @@ nfsd(struct svc_rqst *rqstp) /* Process request with signals blocked. */ sigprocmask(SIG_SETMASK, &allowed_mask, NULL); - svc_process(serv, rqstp); + svc_process(rqstp); /* Unlock export hash tables */ exp_readunlock(); @@ -353,29 +455,13 @@ nfsd(struct svc_rqst *rqstp) if (sigismember(¤t->pending.signal, signo) && !sigismember(¤t->blocked, signo)) break; - err = signo; + killsig = signo; } - /* Clear signals before calling lockd_down() and svc_exit_thread() */ + /* Clear signals before calling svc_exit_thread() */ flush_signals(current); lock_kernel(); - /* Release lockd */ - lockd_down(); - - /* Check if this is last thread */ - if (serv->sv_nrthreads==1) { - - printk(KERN_WARNING "nfsd: last server has exited\n"); - if (err != SIG_NOCLEAN) { - printk(KERN_WARNING "nfsd: unexporting all filesystems\n"); - nfsd_export_flush(); - } - nfsd_serv = NULL; - nfsd_racache_shutdown(); /* release read-ahead cache */ - nfs4_state_shutdown(); - } - list_del(&me.list); nfsdstats.th_cnt --; out: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index c9e3b5a8fe0..443ebc52e38 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1114,7 +1114,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, */ if (!resfhp->fh_dentry) { /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ - fh_lock(fhp); + fh_lock_nested(fhp, I_MUTEX_PARENT); dchild = lookup_one_len(fname, dentry, flen); err = PTR_ERR(dchild); if (IS_ERR(dchild)) @@ -1240,7 +1240,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, err = nfserr_notdir; if(!dirp->i_op || !dirp->i_op->lookup) goto out; - fh_lock(fhp); + fh_lock_nested(fhp, I_MUTEX_PARENT); /* * Compose the response file handle. @@ -1494,7 +1494,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, if (isdotent(name, len)) goto out; - fh_lock(ffhp); + fh_lock_nested(ffhp, I_MUTEX_PARENT); ddir = ffhp->fh_dentry; dirp = ddir->d_inode; @@ -1644,7 +1644,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, if (err) goto out; - fh_lock(fhp); + fh_lock_nested(fhp, I_MUTEX_PARENT); dentry = fhp->fh_dentry; dirp = dentry->d_inode; diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 9de6b495f11..b1317ad5ca1 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -163,8 +163,6 @@ int register_nls(struct nls_table * nls) { struct nls_table ** tmp = &tables; - if (!nls) - return -EINVAL; if (nls->next) return -EBUSY; diff --git a/fs/no-block.c b/fs/no-block.c new file mode 100644 index 00000000000..d269a93d346 --- /dev/null +++ b/fs/no-block.c @@ -0,0 +1,22 @@ +/* no-block.c: implementation of routines required for non-BLOCK configuration + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/fs.h> + +static int no_blkdev_open(struct inode * inode, struct file * filp) +{ + return -ENODEV; +} + +const struct file_operations def_blk_fops = { + .open = no_blkdev_open, +}; diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index bc579bfdfbd..7b2c8f4f6a6 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -254,7 +254,7 @@ static int ntfs_read_block(struct page *page) bh->b_bdev = vol->sb->s_bdev; /* Is the block within the allowed limits? */ if (iblock < lblock) { - BOOL is_retry = FALSE; + bool is_retry = false; /* Convert iblock into corresponding vcn and offset. */ vcn = (VCN)iblock << blocksize_bits >> @@ -292,7 +292,7 @@ lock_retry_remap: goto handle_hole; /* If first try and runlist unmapped, map and retry. */ if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping lock for * the duration. @@ -558,7 +558,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) unsigned long flags; unsigned int blocksize, vcn_ofs; int err; - BOOL need_end_writeback; + bool need_end_writeback; unsigned char blocksize_bits; vi = page->mapping->host; @@ -626,7 +626,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) rl = NULL; err = 0; do { - BOOL is_retry = FALSE; + bool is_retry = false; if (unlikely(block >= dblock)) { /* @@ -768,7 +768,7 @@ lock_retry_remap: } /* If first try and runlist unmapped, map and retry. */ if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping lock for * the duration. @@ -874,12 +874,12 @@ lock_retry_remap: set_page_writeback(page); /* Keeps try_to_free_buffers() away. */ /* Submit the prepared buffers for i/o. */ - need_end_writeback = TRUE; + need_end_writeback = true; do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { submit_bh(WRITE, bh); - need_end_writeback = FALSE; + need_end_writeback = false; } bh = next; } while (bh != head); @@ -932,7 +932,7 @@ static int ntfs_write_mst_block(struct page *page, runlist_element *rl; int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2; unsigned bh_size, rec_size_bits; - BOOL sync, is_mft, page_is_dirty, rec_is_dirty; + bool sync, is_mft, page_is_dirty, rec_is_dirty; unsigned char bh_size_bits; ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " @@ -975,10 +975,10 @@ static int ntfs_write_mst_block(struct page *page, rl = NULL; err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0; - page_is_dirty = rec_is_dirty = FALSE; + page_is_dirty = rec_is_dirty = false; rec_start_bh = NULL; do { - BOOL is_retry = FALSE; + bool is_retry = false; if (likely(block < rec_block)) { if (unlikely(block >= dblock)) { @@ -1009,10 +1009,10 @@ static int ntfs_write_mst_block(struct page *page, } if (!buffer_dirty(bh)) { /* Clean records are not written out. */ - rec_is_dirty = FALSE; + rec_is_dirty = false; continue; } - rec_is_dirty = TRUE; + rec_is_dirty = true; rec_start_bh = bh; } /* Need to map the buffer if it is not mapped already. */ @@ -1053,7 +1053,7 @@ lock_retry_remap: */ if (!is_mft && !is_retry && lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping * lock for the duration. @@ -1063,7 +1063,7 @@ lock_retry_remap: if (likely(!err2)) goto lock_retry_remap; if (err2 == -ENOMEM) - page_is_dirty = TRUE; + page_is_dirty = true; lcn = err2; } else { err2 = -EIO; @@ -1145,7 +1145,7 @@ lock_retry_remap: * means we need to redirty the page before * returning. */ - page_is_dirty = TRUE; + page_is_dirty = true; /* * Remove the buffers in this mft record from * the list of buffers to write. diff --git a/fs/ntfs/aops.h b/fs/ntfs/aops.h index 325ce261a10..9393f4b1e29 100644 --- a/fs/ntfs/aops.h +++ b/fs/ntfs/aops.h @@ -80,7 +80,7 @@ static inline void ntfs_unmap_page(struct page *page) * * The unlocked and uptodate page is returned on success or an encoded error * on failure. Caller has to test for error using the IS_ERR() macro on the - * return value. If that evaluates to TRUE, the negative error code can be + * return value. If that evaluates to 'true', the negative error code can be * obtained using PTR_ERR() on the return value of ntfs_map_page(). */ static inline struct page *ntfs_map_page(struct address_space *mapping, diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 6708e1d68a9..9f08e851cfb 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -67,7 +67,7 @@ * the attribute has zero allocated size, i.e. there simply is no runlist. * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -90,7 +90,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) runlist_element *rl; struct page *put_this_page = NULL; int err = 0; - BOOL ctx_is_temporary, ctx_needs_reset; + bool ctx_is_temporary, ctx_needs_reset; ntfs_attr_search_ctx old_ctx = { NULL, }; ntfs_debug("Mapping runlist part containing vcn 0x%llx.", @@ -100,7 +100,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) else base_ni = ni->ext.base_ntfs_ino; if (!ctx) { - ctx_is_temporary = ctx_needs_reset = TRUE; + ctx_is_temporary = ctx_needs_reset = true; m = map_mft_record(base_ni); if (IS_ERR(m)) return PTR_ERR(m); @@ -115,7 +115,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) BUG_ON(IS_ERR(ctx->mrec)); a = ctx->attr; BUG_ON(!a->non_resident); - ctx_is_temporary = FALSE; + ctx_is_temporary = false; end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn); read_lock_irqsave(&ni->size_lock, flags); allocated_size_vcn = ni->allocated_size >> @@ -136,7 +136,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) ni->name, ni->name_len) && sle64_to_cpu(a->data.non_resident.lowest_vcn) <= vcn && end_vcn >= vcn)) - ctx_needs_reset = FALSE; + ctx_needs_reset = false; else { /* Save the old search context. */ old_ctx = *ctx; @@ -158,7 +158,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) * needed attribute extent. */ ntfs_attr_reinit_search_ctx(ctx); - ctx_needs_reset = TRUE; + ctx_needs_reset = true; } } if (ctx_needs_reset) { @@ -336,16 +336,16 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc). * * Locking: - The runlist must be locked on entry and is left locked on return. - * - If @write_locked is FALSE, i.e. the runlist is locked for reading, + * - If @write_locked is 'false', i.e. the runlist is locked for reading, * the lock may be dropped inside the function so you cannot rely on * the runlist still being the same when this function returns. */ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, - const BOOL write_locked) + const bool write_locked) { LCN lcn; unsigned long flags; - BOOL is_retry = FALSE; + bool is_retry = false; ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", ni->mft_no, (unsigned long long)vcn, @@ -390,7 +390,7 @@ retry_remap: down_read(&ni->runlist.lock); } if (likely(!err)) { - is_retry = TRUE; + is_retry = true; goto retry_remap; } if (err == -ENOENT) @@ -449,7 +449,7 @@ retry_remap: * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -469,7 +469,7 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, unsigned long flags; runlist_element *rl; int err = 0; - BOOL is_retry = FALSE; + bool is_retry = false; ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.", ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out"); @@ -518,7 +518,7 @@ retry_remap: */ err = ntfs_map_runlist_nolock(ni, vcn, ctx); if (likely(!err)) { - is_retry = TRUE; + is_retry = true; goto retry_remap; } } @@ -558,8 +558,8 @@ retry_remap: * On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is * undefined and in particular do not rely on it not changing. * - * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it - * is FALSE, the search begins after @ctx->attr. + * If @ctx->is_first is 'true', the search begins with @ctx->attr itself. If it + * is 'false', the search begins after @ctx->attr. * * If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record @@ -599,11 +599,11 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name, /* * Iterate over attributes in mft record starting at @ctx->attr, or the - * attribute following that, if @ctx->is_first is TRUE. + * attribute following that, if @ctx->is_first is 'true'. */ if (ctx->is_first) { a = ctx->attr; - ctx->is_first = FALSE; + ctx->is_first = false; } else a = (ATTR_RECORD*)((u8*)ctx->attr + le32_to_cpu(ctx->attr->length)); @@ -890,11 +890,11 @@ static int ntfs_external_attr_find(const ATTR_TYPE type, ctx->al_entry = (ATTR_LIST_ENTRY*)al_start; /* * Iterate over entries in attribute list starting at @ctx->al_entry, - * or the entry following that, if @ctx->is_first is TRUE. + * or the entry following that, if @ctx->is_first is 'true'. */ if (ctx->is_first) { al_entry = ctx->al_entry; - ctx->is_first = FALSE; + ctx->is_first = false; } else al_entry = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry + le16_to_cpu(ctx->al_entry->length)); @@ -1127,7 +1127,7 @@ not_found: ctx->mrec = ctx->base_mrec; ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec + le16_to_cpu(ctx->mrec->attrs_offset)); - ctx->is_first = TRUE; + ctx->is_first = true; ctx->ntfs_ino = base_ni; ctx->base_ntfs_ino = NULL; ctx->base_mrec = NULL; @@ -1224,7 +1224,7 @@ static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx, /* Sanity checks are performed elsewhere. */ .attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset)), - .is_first = TRUE, + .is_first = true, .ntfs_ino = ni, }; } @@ -1243,7 +1243,7 @@ void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx) { if (likely(!ctx->base_ntfs_ino)) { /* No attribute list. */ - ctx->is_first = TRUE; + ctx->is_first = true; /* Sanity checks are performed elsewhere. */ ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec + le16_to_cpu(ctx->mrec->attrs_offset)); @@ -1585,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) return -ENOMEM; /* Start by allocating clusters to hold the attribute value. */ rl = ntfs_cluster_alloc(vol, 0, new_size >> - vol->cluster_size_bits, -1, DATA_ZONE, TRUE); + vol->cluster_size_bits, -1, DATA_ZONE, true); if (IS_ERR(rl)) { err = PTR_ERR(rl); ntfs_debug("Failed to allocate cluster%s, error code " @@ -1919,7 +1919,7 @@ s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size, unsigned long flags; int err, mp_size; u32 attr_len = 0; /* Silence stupid gcc warning. */ - BOOL mp_rebuilt; + bool mp_rebuilt; #ifdef NTFS_DEBUG read_lock_irqsave(&ni->size_lock, flags); @@ -2222,7 +2222,7 @@ first_alloc: rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits, (new_alloc_size - allocated_size) >> vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ? - rl->lcn + rl->length : -1, DATA_ZONE, TRUE); + rl->lcn + rl->length : -1, DATA_ZONE, true); if (IS_ERR(rl2)) { err = PTR_ERR(rl2); if (start < 0 || start >= allocated_size) @@ -2265,7 +2265,7 @@ first_alloc: BUG_ON(!rl2); BUG_ON(!rl2->length); BUG_ON(rl2->lcn < LCN_HOLE); - mp_rebuilt = FALSE; + mp_rebuilt = false; /* Get the size for the new mapping pairs array for this extent. */ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); if (unlikely(mp_size <= 0)) { @@ -2300,7 +2300,7 @@ first_alloc: err = -EOPNOTSUPP; goto undo_alloc; } - mp_rebuilt = TRUE; + mp_rebuilt = true; /* Generate the mapping pairs array directly into the attr record. */ err = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(a->data.non_resident.mapping_pairs_offset), diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index 9074886b44b..3c8b74c99b8 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -40,10 +40,10 @@ * Structure must be initialized to zero before the first call to one of the * attribute search functions. Initialize @mrec to point to the mft record to * search, and @attr to point to the first attribute within @mrec (not necessary - * if calling the _first() functions), and set @is_first to TRUE (not necessary + * if calling the _first() functions), and set @is_first to 'true' (not necessary * if calling the _first() functions). * - * If @is_first is TRUE, the search begins with @attr. If @is_first is FALSE, + * If @is_first is 'true', the search begins with @attr. If @is_first is 'false', * the search begins after @attr. This is so that, after the first call to one * of the search attribute functions, we can call the function again, without * any modification of the search context, to automagically get the next @@ -52,7 +52,7 @@ typedef struct { MFT_RECORD *mrec; ATTR_RECORD *attr; - BOOL is_first; + bool is_first; ntfs_inode *ntfs_ino; ATTR_LIST_ENTRY *al_entry; ntfs_inode *base_ntfs_ino; @@ -65,7 +65,7 @@ extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn); extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, - const BOOL write_locked); + const bool write_locked); extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, ntfs_attr_search_ctx *ctx); diff --git a/fs/ntfs/bitmap.c b/fs/ntfs/bitmap.c index 7a190cdc60e..0809cf87609 100644 --- a/fs/ntfs/bitmap.c +++ b/fs/ntfs/bitmap.c @@ -34,18 +34,18 @@ * @start_bit: first bit to set * @count: number of bits to set * @value: value to set the bits to (i.e. 0 or 1) - * @is_rollback: if TRUE this is a rollback operation + * @is_rollback: if 'true' this is a rollback operation * * Set @count bits starting at bit @start_bit in the bitmap described by the * vfs inode @vi to @value, where @value is either 0 or 1. * - * @is_rollback should always be FALSE, it is for internal use to rollback + * @is_rollback should always be 'false', it is for internal use to rollback * errors. You probably want to use ntfs_bitmap_set_bits_in_run() instead. * * Return 0 on success and -errno on error. */ int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit, - const s64 count, const u8 value, const BOOL is_rollback) + const s64 count, const u8 value, const bool is_rollback) { s64 cnt = count; pgoff_t index, end_index; @@ -172,7 +172,7 @@ rollback: return PTR_ERR(page); if (count != cnt) pos = __ntfs_bitmap_set_bits_in_run(vi, start_bit, count - cnt, - value ? 0 : 1, TRUE); + value ? 0 : 1, true); else pos = 0; if (!pos) { diff --git a/fs/ntfs/bitmap.h b/fs/ntfs/bitmap.h index bb50d6bc921..72c9ad8be70 100644 --- a/fs/ntfs/bitmap.h +++ b/fs/ntfs/bitmap.h @@ -30,7 +30,7 @@ #include "types.h" extern int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit, - const s64 count, const u8 value, const BOOL is_rollback); + const s64 count, const u8 value, const bool is_rollback); /** * ntfs_bitmap_set_bits_in_run - set a run of bits in a bitmap to a value @@ -48,7 +48,7 @@ static inline int ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit, const s64 count, const u8 value) { return __ntfs_bitmap_set_bits_in_run(vi, start_bit, count, value, - FALSE); + false); } /** diff --git a/fs/ntfs/collate.h b/fs/ntfs/collate.h index e027f36fcc2..aba83347e5f 100644 --- a/fs/ntfs/collate.h +++ b/fs/ntfs/collate.h @@ -26,7 +26,7 @@ #include "types.h" #include "volume.h" -static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULE cr) { +static inline bool ntfs_is_collation_rule_supported(COLLATION_RULE cr) { int i; /* @@ -35,12 +35,12 @@ static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULE cr) { * now. */ if (unlikely(cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG)) - return FALSE; + return false; i = le32_to_cpu(cr); if (likely(((i >= 0) && (i <= 0x02)) || ((i >= 0x10) && (i <= 0x13)))) - return TRUE; - return FALSE; + return true; + return false; } extern int ntfs_collate(ntfs_volume *vol, COLLATION_RULE cr, diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index 68a607ff9fd..d98daf59e0b 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -600,7 +600,7 @@ do_next_cb: rl = NULL; for (vcn = start_vcn, start_vcn += cb_clusters; vcn < start_vcn; vcn++) { - BOOL is_retry = FALSE; + bool is_retry = false; if (!rl) { lock_retry_remap: @@ -626,7 +626,7 @@ lock_retry_remap: break; if (is_retry || lcn != LCN_RL_NOT_MAPPED) goto rl_err; - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping lock for the * duration. diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 2e42c2dcae1..ae2fe0016d2 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -509,7 +509,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, u32 attr_rec_len = 0; unsigned blocksize, u; int err, mp_size; - BOOL rl_write_locked, was_hole, is_retry; + bool rl_write_locked, was_hole, is_retry; unsigned char blocksize_bits; struct { u8 runlist_merged:1; @@ -543,13 +543,13 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, return -ENOMEM; } } while (++u < nr_pages); - rl_write_locked = FALSE; + rl_write_locked = false; rl = NULL; err = 0; vcn = lcn = -1; vcn_len = 0; lcn_block = -1; - was_hole = FALSE; + was_hole = false; cpos = pos >> vol->cluster_size_bits; end = pos + bytes; cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits; @@ -760,7 +760,7 @@ map_buffer_cached: } continue; } - is_retry = FALSE; + is_retry = false; if (!rl) { down_read(&ni->runlist.lock); retry_remap: @@ -776,7 +776,7 @@ retry_remap: * Successful remap, setup the map cache and * use that to deal with the buffer. */ - was_hole = FALSE; + was_hole = false; vcn = bh_cpos; vcn_len = rl[1].vcn - vcn; lcn_block = lcn << (vol->cluster_size_bits - @@ -792,7 +792,7 @@ retry_remap: if (likely(vcn + vcn_len >= cend)) { if (rl_write_locked) { up_write(&ni->runlist.lock); - rl_write_locked = FALSE; + rl_write_locked = false; } else up_read(&ni->runlist.lock); rl = NULL; @@ -818,13 +818,13 @@ retry_remap: */ up_read(&ni->runlist.lock); down_write(&ni->runlist.lock); - rl_write_locked = TRUE; + rl_write_locked = true; goto retry_remap; } err = ntfs_map_runlist_nolock(ni, bh_cpos, NULL); if (likely(!err)) { - is_retry = TRUE; + is_retry = true; goto retry_remap; } /* @@ -903,7 +903,7 @@ rl_not_mapped_enoent: if (!rl_write_locked) { up_read(&ni->runlist.lock); down_write(&ni->runlist.lock); - rl_write_locked = TRUE; + rl_write_locked = true; goto retry_remap; } /* Find the previous last allocated cluster. */ @@ -917,7 +917,7 @@ rl_not_mapped_enoent: } } rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE, - FALSE); + false); if (IS_ERR(rl2)) { err = PTR_ERR(rl2); ntfs_debug("Failed to allocate cluster, error code %i.", @@ -1093,7 +1093,7 @@ rl_not_mapped_enoent: status.mft_attr_mapped = 0; status.mp_rebuilt = 0; /* Setup the map cache and use that to deal with the buffer. */ - was_hole = TRUE; + was_hole = true; vcn = bh_cpos; vcn_len = 1; lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits); @@ -1105,7 +1105,7 @@ rl_not_mapped_enoent: */ if (likely(vcn + vcn_len >= cend)) { up_write(&ni->runlist.lock); - rl_write_locked = FALSE; + rl_write_locked = false; rl = NULL; } goto map_buffer_cached; @@ -1117,7 +1117,7 @@ rl_not_mapped_enoent: if (likely(!err)) { if (unlikely(rl_write_locked)) { up_write(&ni->runlist.lock); - rl_write_locked = FALSE; + rl_write_locked = false; } else if (unlikely(rl)) up_read(&ni->runlist.lock); rl = NULL; @@ -1528,19 +1528,19 @@ static inline int ntfs_commit_pages_after_non_resident_write( do { s64 bh_pos; struct page *page; - BOOL partial; + bool partial; page = pages[u]; bh_pos = (s64)page->index << PAGE_CACHE_SHIFT; bh = head = page_buffers(page); - partial = FALSE; + partial = false; do { s64 bh_end; bh_end = bh_pos + blocksize; if (bh_end <= pos || bh_pos >= end) { if (!buffer_uptodate(bh)) - partial = TRUE; + partial = true; } else { set_buffer_uptodate(bh); mark_buffer_dirty(bh); @@ -1997,7 +1997,7 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, */ down_read(&ni->runlist.lock); lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >> - vol->cluster_size_bits, FALSE); + vol->cluster_size_bits, false); up_read(&ni->runlist.lock); if (unlikely(lcn < LCN_HOLE)) { status = -EIO; @@ -2176,20 +2176,18 @@ out: /** * ntfs_file_aio_write - */ -static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) +static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; ssize_t ret; - struct iovec local_iov = { .iov_base = (void __user *)buf, - .iov_len = count }; BUG_ON(iocb->ki_pos != pos); mutex_lock(&inode->i_mutex); - ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); + ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos); mutex_unlock(&inode->i_mutex); if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { int err = sync_page_range(inode, mapping, pos, ret); @@ -2298,13 +2296,11 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, const struct file_operations ntfs_file_ops = { .llseek = generic_file_llseek, /* Seek inside file. */ - .read = generic_file_read, /* Read from file. */ + .read = do_sync_read, /* Read from file. */ .aio_read = generic_file_aio_read, /* Async read from file. */ - .readv = generic_file_readv, /* Read from file. */ #ifdef NTFS_RW .write = ntfs_file_write, /* Write to file. */ .aio_write = ntfs_file_aio_write, /* Async write to file. */ - .writev = ntfs_file_writev, /* Write to file. */ /*.release = ,*/ /* Last file is closed. See fs/ext2/file.c:: ext2_release_file() for diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c index 9f5427c2d10..e32cde48636 100644 --- a/fs/ntfs/index.c +++ b/fs/ntfs/index.c @@ -204,7 +204,7 @@ int ntfs_index_lookup(const void *key, const int key_len, if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key, &ie->key, key_len)) { ir_done: - ictx->is_in_root = TRUE; + ictx->is_in_root = true; ictx->ir = ir; ictx->actx = actx; ictx->base_ni = base_ni; @@ -374,7 +374,7 @@ fast_descend_into_child_node: if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key, &ie->key, key_len)) { ia_done: - ictx->is_in_root = FALSE; + ictx->is_in_root = false; ictx->actx = NULL; ictx->base_ni = NULL; ictx->ia = ia; diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h index 846a489e869..8745469c398 100644 --- a/fs/ntfs/index.h +++ b/fs/ntfs/index.h @@ -37,12 +37,12 @@ * @entry: index entry (points into @ir or @ia) * @data: index entry data (points into @entry) * @data_len: length in bytes of @data - * @is_in_root: TRUE if @entry is in @ir and FALSE if it is in @ia + * @is_in_root: 'true' if @entry is in @ir and 'false' if it is in @ia * @ir: index root if @is_in_root and NULL otherwise * @actx: attribute search context if @is_in_root and NULL otherwise * @base_ni: base inode if @is_in_root and NULL otherwise - * @ia: index block if @is_in_root is FALSE and NULL otherwise - * @page: page if @is_in_root is FALSE and NULL otherwise + * @ia: index block if @is_in_root is 'false' and NULL otherwise + * @page: page if @is_in_root is 'false' and NULL otherwise * * @idx_ni is the index inode this context belongs to. * @@ -50,11 +50,11 @@ * are the index entry data and its length in bytes, respectively. @data * simply points into @entry. This is probably what the user is interested in. * - * If @is_in_root is TRUE, @entry is in the index root attribute @ir described + * If @is_in_root is 'true', @entry is in the index root attribute @ir described * by the attribute search context @actx and the base inode @base_ni. @ia and * @page are NULL in this case. * - * If @is_in_root is FALSE, @entry is in the index allocation attribute and @ia + * If @is_in_root is 'false', @entry is in the index allocation attribute and @ia * and @page point to the index allocation block and the mapped, locked page it * is in, respectively. @ir, @actx and @base_ni are NULL in this case. * @@ -77,7 +77,7 @@ typedef struct { INDEX_ENTRY *entry; void *data; u16 data_len; - BOOL is_in_root; + bool is_in_root; INDEX_ROOT *ir; ntfs_attr_search_ctx *actx; ntfs_inode *base_ni; diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 933dbd89c2a..2d3de9c8981 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2301,7 +2301,7 @@ void ntfs_clear_big_inode(struct inode *vi) } #ifdef NTFS_RW if (NInoDirty(ni)) { - BOOL was_bad = (is_bad_inode(vi)); + bool was_bad = (is_bad_inode(vi)); /* Committing the inode also commits all extent inodes. */ ntfs_commit_inode(vi); @@ -3015,7 +3015,7 @@ int ntfs_write_inode(struct inode *vi, int sync) MFT_RECORD *m; STANDARD_INFORMATION *si; int err = 0; - BOOL modified = FALSE; + bool modified = false; ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "", vi->i_ino); @@ -3057,7 +3057,7 @@ int ntfs_write_inode(struct inode *vi, int sync) sle64_to_cpu(si->last_data_change_time), (long long)sle64_to_cpu(nt)); si->last_data_change_time = nt; - modified = TRUE; + modified = true; } nt = utc2ntfs(vi->i_ctime); if (si->last_mft_change_time != nt) { @@ -3066,7 +3066,7 @@ int ntfs_write_inode(struct inode *vi, int sync) sle64_to_cpu(si->last_mft_change_time), (long long)sle64_to_cpu(nt)); si->last_mft_change_time = nt; - modified = TRUE; + modified = true; } nt = utc2ntfs(vi->i_atime); if (si->last_access_time != nt) { @@ -3075,7 +3075,7 @@ int ntfs_write_inode(struct inode *vi, int sync) (long long)sle64_to_cpu(si->last_access_time), (long long)sle64_to_cpu(nt)); si->last_access_time = nt; - modified = TRUE; + modified = true; } /* * If we just modified the standard information attribute we need to diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index d34b93cb8b4..1e383328ece 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h @@ -142,13 +142,13 @@ typedef le32 NTFS_RECORD_TYPE; * operator! (-8 */ -static inline BOOL __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r) +static inline bool __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r) { return (x == r); } #define ntfs_is_magic(x, m) __ntfs_is_magic(x, magic_##m) -static inline BOOL __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r) +static inline bool __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r) { return (*p == r); } @@ -323,7 +323,7 @@ typedef le64 leMFT_REF; #define MREF_LE(x) ((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU)) #define MSEQNO_LE(x) ((u16)((le64_to_cpu(x) >> 48) & 0xffff)) -#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? 1 : 0) +#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? true : false) #define ERR_MREF(x) ((u64)((s64)(x))) #define MREF_ERR(x) ((int)((s64)(x))) diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 29cabf93d2d..1711b710b64 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -76,7 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, * @count: number of clusters to allocate * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) * @zone: zone from which to allocate the clusters - * @is_extension: if TRUE, this is an attribute extension + * @is_extension: if 'true', this is an attribute extension * * Allocate @count clusters preferably starting at cluster @start_lcn or at the * current allocator position if @start_lcn is -1, on the mounted ntfs volume @@ -87,11 +87,11 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, * @start_vcn specifies the vcn of the first allocated cluster. This makes * merging the resulting runlist with the old runlist easier. * - * If @is_extension is TRUE, the caller is allocating clusters to extend an - * attribute and if it is FALSE, the caller is allocating clusters to fill a + * If @is_extension is 'true', the caller is allocating clusters to extend an + * attribute and if it is 'false', the caller is allocating clusters to fill a * hole in an attribute. Practically the difference is that if @is_extension - * is TRUE the returned runlist will be terminated with LCN_ENOENT and if - * @is_extension is FALSE the runlist will be terminated with + * is 'true' the returned runlist will be terminated with LCN_ENOENT and if + * @is_extension is 'false' the runlist will be terminated with * LCN_RL_NOT_MAPPED. * * You need to check the return value with IS_ERR(). If this is false, the @@ -146,7 +146,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, const s64 count, const LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone, - const BOOL is_extension) + const bool is_extension) { LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; @@ -818,7 +818,7 @@ out: * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that * you cache ctx->mrec in a variable @m of type MFT_RECORD *. * - * @is_rollback should always be FALSE, it is for internal use to rollback + * @is_rollback should always be 'false', it is for internal use to rollback * errors. You probably want to use ntfs_cluster_free() instead. * * Note, __ntfs_cluster_free() does not modify the runlist, so you have to @@ -828,7 +828,7 @@ out: * success and -errno on error. * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -847,7 +847,7 @@ out: * and it will be left mapped on return. */ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, - ntfs_attr_search_ctx *ctx, const BOOL is_rollback) + ntfs_attr_search_ctx *ctx, const bool is_rollback) { s64 delta, to_free, total_freed, real_freed; ntfs_volume *vol; @@ -999,7 +999,7 @@ err_out: * If rollback fails, set the volume errors flag, emit an error * message, and return the error code. */ - delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE); + delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, true); if (delta < 0) { ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " "inconsistent metadata! Unmount and run " diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h index 72cbca7003b..2adb0431694 100644 --- a/fs/ntfs/lcnalloc.h +++ b/fs/ntfs/lcnalloc.h @@ -43,10 +43,10 @@ typedef enum { extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, const s64 count, const LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone, - const BOOL is_extension); + const bool is_extension); extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, - s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback); + s64 count, ntfs_attr_search_ctx *ctx, const bool is_rollback); /** * ntfs_cluster_free - free clusters on an ntfs volume @@ -86,7 +86,7 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, * success and -errno on error. * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -107,7 +107,7 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, ntfs_attr_search_ctx *ctx) { - return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE); + return __ntfs_cluster_free(ni, start_vcn, count, ctx, false); } extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index 4af2ad1193e..acfed325f4e 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c @@ -41,18 +41,18 @@ * @rp: restart page header to check * @pos: position in @vi at which the restart page header resides * - * Check the restart page header @rp for consistency and return TRUE if it is - * consistent and FALSE otherwise. + * Check the restart page header @rp for consistency and return 'true' if it is + * consistent and 'false' otherwise. * * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not * require the full restart page. */ -static BOOL ntfs_check_restart_page_header(struct inode *vi, +static bool ntfs_check_restart_page_header(struct inode *vi, RESTART_PAGE_HEADER *rp, s64 pos) { u32 logfile_system_page_size, logfile_log_page_size; u16 ra_ofs, usa_count, usa_ofs, usa_end = 0; - BOOL have_usa = TRUE; + bool have_usa = true; ntfs_debug("Entering."); /* @@ -67,7 +67,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, (logfile_system_page_size - 1) || logfile_log_page_size & (logfile_log_page_size - 1)) { ntfs_error(vi->i_sb, "$LogFile uses unsupported page size."); - return FALSE; + return false; } /* * We must be either at !pos (1st restart page) or at pos = system page @@ -76,7 +76,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, if (pos && pos != logfile_system_page_size) { ntfs_error(vi->i_sb, "Found restart area in incorrect " "position in $LogFile."); - return FALSE; + return false; } /* We only know how to handle version 1.1. */ if (sle16_to_cpu(rp->major_ver) != 1 || @@ -85,14 +85,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, "supported. (This driver supports version " "1.1 only.)", (int)sle16_to_cpu(rp->major_ver), (int)sle16_to_cpu(rp->minor_ver)); - return FALSE; + return false; } /* * If chkdsk has been run the restart page may not be protected by an * update sequence array. */ if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) { - have_usa = FALSE; + have_usa = false; goto skip_usa_checks; } /* Verify the size of the update sequence array. */ @@ -100,7 +100,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, if (usa_count != le16_to_cpu(rp->usa_count)) { ntfs_error(vi->i_sb, "$LogFile restart page specifies " "inconsistent update sequence array count."); - return FALSE; + return false; } /* Verify the position of the update sequence array. */ usa_ofs = le16_to_cpu(rp->usa_ofs); @@ -109,7 +109,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) { ntfs_error(vi->i_sb, "$LogFile restart page specifies " "inconsistent update sequence array offset."); - return FALSE; + return false; } skip_usa_checks: /* @@ -124,7 +124,7 @@ skip_usa_checks: ra_ofs > logfile_system_page_size) { ntfs_error(vi->i_sb, "$LogFile restart page specifies " "inconsistent restart area offset."); - return FALSE; + return false; } /* * Only restart pages modified by chkdsk are allowed to have chkdsk_lsn @@ -133,10 +133,10 @@ skip_usa_checks: if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) { ntfs_error(vi->i_sb, "$LogFile restart page is not modified " "by chkdsk but a chkdsk LSN is specified."); - return FALSE; + return false; } ntfs_debug("Done."); - return TRUE; + return true; } /** @@ -145,7 +145,7 @@ skip_usa_checks: * @rp: restart page whose restart area to check * * Check the restart area of the restart page @rp for consistency and return - * TRUE if it is consistent and FALSE otherwise. + * 'true' if it is consistent and 'false' otherwise. * * This function assumes that the restart page header has already been * consistency checked. @@ -153,7 +153,7 @@ skip_usa_checks: * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not * require the full restart page. */ -static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) +static bool ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) { u64 file_size; RESTART_AREA *ra; @@ -172,7 +172,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) NTFS_BLOCK_SIZE - sizeof(u16)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent file offset."); - return FALSE; + return false; } /* * Now that we can access ra->client_array_offset, make sure everything @@ -186,7 +186,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent client array offset."); - return FALSE; + return false; } /* * The restart area must end within the system page size both when @@ -203,7 +203,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) "of the system page size specified by the " "restart page header and/or the specified " "restart area length is inconsistent."); - return FALSE; + return false; } /* * The ra->client_free_list and ra->client_in_use_list must be either @@ -218,7 +218,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) le16_to_cpu(ra->log_clients))) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "overflowing client free and/or in use lists."); - return FALSE; + return false; } /* * Check ra->seq_number_bits against ra->file_size for consistency. @@ -233,24 +233,24 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) if (le32_to_cpu(ra->seq_number_bits) != 67 - fs_bits) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent sequence number bits."); - return FALSE; + return false; } /* The log record header length must be a multiple of 8. */ if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) != le16_to_cpu(ra->log_record_header_length)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent log record header length."); - return FALSE; + return false; } /* Dito for the log page data offset. */ if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) != le16_to_cpu(ra->log_page_data_offset)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent log page data offset."); - return FALSE; + return false; } ntfs_debug("Done."); - return TRUE; + return true; } /** @@ -259,7 +259,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) * @rp: restart page whose log client array to check * * Check the log client array of the restart page @rp for consistency and - * return TRUE if it is consistent and FALSE otherwise. + * return 'true' if it is consistent and 'false' otherwise. * * This function assumes that the restart page header and the restart area have * already been consistency checked. @@ -268,13 +268,13 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) * function needs @rp->system_page_size bytes in @rp, i.e. it requires the full * restart page and the page must be multi sector transfer deprotected. */ -static BOOL ntfs_check_log_client_array(struct inode *vi, +static bool ntfs_check_log_client_array(struct inode *vi, RESTART_PAGE_HEADER *rp) { RESTART_AREA *ra; LOG_CLIENT_RECORD *ca, *cr; u16 nr_clients, idx; - BOOL in_free_list, idx_is_first; + bool in_free_list, idx_is_first; ntfs_debug("Entering."); ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); @@ -290,9 +290,9 @@ static BOOL ntfs_check_log_client_array(struct inode *vi, */ nr_clients = le16_to_cpu(ra->log_clients); idx = le16_to_cpu(ra->client_free_list); - in_free_list = TRUE; + in_free_list = true; check_list: - for (idx_is_first = TRUE; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, + for (idx_is_first = true; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, idx = le16_to_cpu(cr->next_client)) { if (!nr_clients || idx >= le16_to_cpu(ra->log_clients)) goto err_out; @@ -302,20 +302,20 @@ check_list: if (idx_is_first) { if (cr->prev_client != LOGFILE_NO_CLIENT) goto err_out; - idx_is_first = FALSE; + idx_is_first = false; } } /* Switch to and check the in use list if we just did the free list. */ if (in_free_list) { - in_free_list = FALSE; + in_free_list = false; idx = le16_to_cpu(ra->client_in_use_list); goto check_list; } ntfs_debug("Done."); - return TRUE; + return true; err_out: ntfs_error(vi->i_sb, "$LogFile log client array is corrupt."); - return FALSE; + return false; } /** @@ -468,8 +468,8 @@ err_out: * @log_vi: struct inode of loaded journal $LogFile to check * @rp: [OUT] on success this is a copy of the current restart page * - * Check the $LogFile journal for consistency and return TRUE if it is - * consistent and FALSE if not. On success, the current restart page is + * Check the $LogFile journal for consistency and return 'true' if it is + * consistent and 'false' if not. On success, the current restart page is * returned in *@rp. Caller must call ntfs_free(*@rp) when finished with it. * * At present we only check the two restart pages and ignore the log record @@ -480,7 +480,7 @@ err_out: * if the $LogFile was created on a system with a different page size to ours * yet and mst deprotection would fail if our page size is smaller. */ -BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) +bool ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) { s64 size, pos; LSN rstr1_lsn, rstr2_lsn; @@ -491,7 +491,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) RESTART_PAGE_HEADER *rstr1_ph = NULL; RESTART_PAGE_HEADER *rstr2_ph = NULL; int log_page_size, log_page_mask, err; - BOOL logfile_is_empty = TRUE; + bool logfile_is_empty = true; u8 log_page_bits; ntfs_debug("Entering."); @@ -527,7 +527,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) if (size < log_page_size * 2 || (size - log_page_size * 2) >> log_page_bits < MinLogRecordPages) { ntfs_error(vol->sb, "$LogFile is too small."); - return FALSE; + return false; } /* * Read through the file looking for a restart page. Since the restart @@ -556,7 +556,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) * means we are done. */ if (!ntfs_is_empty_recordp((le32*)kaddr)) - logfile_is_empty = FALSE; + logfile_is_empty = false; else if (!logfile_is_empty) break; /* @@ -615,13 +615,13 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) NVolSetLogFileEmpty(vol); is_empty: ntfs_debug("Done. ($LogFile is empty.)"); - return TRUE; + return true; } if (!rstr1_ph) { BUG_ON(rstr2_ph); ntfs_error(vol->sb, "Did not find any restart pages in " "$LogFile and it was not empty."); - return FALSE; + return false; } /* If both restart pages were found, use the more recent one. */ if (rstr2_ph) { @@ -648,11 +648,11 @@ is_empty: else ntfs_free(rstr1_ph); ntfs_debug("Done."); - return TRUE; + return true; err_out: if (rstr1_ph) ntfs_free(rstr1_ph); - return FALSE; + return false; } /** @@ -660,8 +660,8 @@ err_out: * @log_vi: struct inode of loaded journal $LogFile to check * @rp: copy of the current restart page * - * Analyze the $LogFile journal and return TRUE if it indicates the volume was - * shutdown cleanly and FALSE if not. + * Analyze the $LogFile journal and return 'true' if it indicates the volume was + * shutdown cleanly and 'false' if not. * * At present we only look at the two restart pages and ignore the log record * pages. This is a little bit crude in that there will be a very small number @@ -675,7 +675,7 @@ err_out: * is empty this function requires that NVolLogFileEmpty() is true otherwise an * empty volume will be reported as dirty. */ -BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) +bool ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) { ntfs_volume *vol = NTFS_SB(log_vi->i_sb); RESTART_AREA *ra; @@ -684,7 +684,7 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) /* An empty $LogFile must have been clean before it got emptied. */ if (NVolLogFileEmpty(vol)) { ntfs_debug("Done. ($LogFile is empty.)"); - return TRUE; + return true; } BUG_ON(!rp); if (!ntfs_is_rstr_record(rp->magic) && @@ -693,7 +693,7 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) "probably a bug in that the $LogFile should " "have been consistency checked before calling " "this function."); - return FALSE; + return false; } ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); /* @@ -704,25 +704,25 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) if (ra->client_in_use_list != LOGFILE_NO_CLIENT && !(ra->flags & RESTART_VOLUME_IS_CLEAN)) { ntfs_debug("Done. $LogFile indicates a dirty shutdown."); - return FALSE; + return false; } /* $LogFile indicates a clean shutdown. */ ntfs_debug("Done. $LogFile indicates a clean shutdown."); - return TRUE; + return true; } /** * ntfs_empty_logfile - empty the contents of the $LogFile journal * @log_vi: struct inode of loaded journal $LogFile to empty * - * Empty the contents of the $LogFile journal @log_vi and return TRUE on - * success and FALSE on error. + * Empty the contents of the $LogFile journal @log_vi and return 'true' on + * success and 'false' on error. * * This function assumes that the $LogFile journal has already been consistency * checked by a call to ntfs_check_logfile() and that ntfs_is_logfile_clean() * has been used to ensure that the $LogFile is clean. */ -BOOL ntfs_empty_logfile(struct inode *log_vi) +bool ntfs_empty_logfile(struct inode *log_vi) { ntfs_volume *vol = NTFS_SB(log_vi->i_sb); @@ -735,13 +735,13 @@ BOOL ntfs_empty_logfile(struct inode *log_vi) if (unlikely(err)) { ntfs_error(vol->sb, "Failed to fill $LogFile with " "0xff bytes (error code %i).", err); - return FALSE; + return false; } /* Set the flag so we do not have to do it again on remount. */ NVolSetLogFileEmpty(vol); } ntfs_debug("Done."); - return TRUE; + return true; } #endif /* NTFS_RW */ diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h index a51f3dd0e9e..9468e1c45ae 100644 --- a/fs/ntfs/logfile.h +++ b/fs/ntfs/logfile.h @@ -296,13 +296,13 @@ typedef struct { /* sizeof() = 160 (0xa0) bytes */ } __attribute__ ((__packed__)) LOG_CLIENT_RECORD; -extern BOOL ntfs_check_logfile(struct inode *log_vi, +extern bool ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp); -extern BOOL ntfs_is_logfile_clean(struct inode *log_vi, +extern bool ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp); -extern BOOL ntfs_empty_logfile(struct inode *log_vi); +extern bool ntfs_empty_logfile(struct inode *log_vi); #endif /* NTFS_RW */ diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 584260fd684..2ad5c8b104b 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -251,7 +251,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, int i; unsigned long mft_no = MREF(mref); u16 seq_no = MSEQNO(mref); - BOOL destroy_ni = FALSE; + bool destroy_ni = false; ntfs_debug("Mapping extent mft record 0x%lx (base mft record 0x%lx).", mft_no, base_ni->mft_no); @@ -322,7 +322,7 @@ map_err_out: if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { ntfs_error(base_ni->vol->sb, "Found stale extent mft " "reference! Corrupt filesystem. Run chkdsk."); - destroy_ni = TRUE; + destroy_ni = true; m = ERR_PTR(-EIO); goto unm_err_out; } @@ -335,7 +335,7 @@ map_err_out: if (unlikely(!tmp)) { ntfs_error(base_ni->vol->sb, "Failed to allocate " "internal buffer."); - destroy_ni = TRUE; + destroy_ni = true; m = ERR_PTR(-ENOMEM); goto unm_err_out; } @@ -857,7 +857,7 @@ err_out: * caller is responsible for unlocking the ntfs inode and unpinning the base * vfs inode. * - * Return TRUE if the mft record may be written out and FALSE if not. + * Return 'true' if the mft record may be written out and 'false' if not. * * The caller has locked the page and cleared the uptodate flag on it which * means that we can safely write out any dirty mft records that do not have @@ -868,7 +868,7 @@ err_out: * Here is a description of the tests we perform: * * If the inode is found in icache we know the mft record must be a base mft - * record. If it is dirty, we do not write it and return FALSE as the vfs + * record. If it is dirty, we do not write it and return 'false' as the vfs * inode write paths will result in the access times being updated which would * cause the base mft record to be redirtied and written out again. (We know * the access time update will modify the base mft record because Windows @@ -877,11 +877,11 @@ err_out: * * If the inode is in icache and not dirty, we attempt to lock the mft record * and if we find the lock was already taken, it is not safe to write the mft - * record and we return FALSE. + * record and we return 'false'. * * If we manage to obtain the lock we have exclusive access to the mft record, * which also allows us safe writeout of the mft record. We then set - * @locked_ni to the locked ntfs inode and return TRUE. + * @locked_ni to the locked ntfs inode and return 'true'. * * Note we cannot just lock the mft record and sleep while waiting for the lock * because this would deadlock due to lock reversal (normally the mft record is @@ -891,24 +891,24 @@ err_out: * If the inode is not in icache we need to perform further checks. * * If the mft record is not a FILE record or it is a base mft record, we can - * safely write it and return TRUE. + * safely write it and return 'true'. * * We now know the mft record is an extent mft record. We check if the inode * corresponding to its base mft record is in icache and obtain a reference to - * it if it is. If it is not, we can safely write it and return TRUE. + * it if it is. If it is not, we can safely write it and return 'true'. * * We now have the base inode for the extent mft record. We check if it has an * ntfs inode for the extent mft record attached and if not it is safe to write - * the extent mft record and we return TRUE. + * the extent mft record and we return 'true'. * * The ntfs inode for the extent mft record is attached to the base inode so we * attempt to lock the extent mft record and if we find the lock was already - * taken, it is not safe to write the extent mft record and we return FALSE. + * taken, it is not safe to write the extent mft record and we return 'false'. * * If we manage to obtain the lock we have exclusive access to the extent mft * record, which also allows us safe writeout of the extent mft record. We * set the ntfs inode of the extent mft record clean and then set @locked_ni to - * the now locked ntfs inode and return TRUE. + * the now locked ntfs inode and return 'true'. * * Note, the reason for actually writing dirty mft records here and not just * relying on the vfs inode dirty code paths is that we can have mft records @@ -922,7 +922,7 @@ err_out: * appear if the mft record is reused for a new inode before it got written * out. */ -BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, +bool ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, const MFT_RECORD *m, ntfs_inode **locked_ni) { struct super_block *sb = vol->sb; @@ -977,7 +977,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, mft_no); atomic_dec(&ni->count); iput(vi); - return FALSE; + return false; } ntfs_debug("Inode 0x%lx is not dirty.", mft_no); /* The inode is not dirty, try to take the mft record lock. */ @@ -986,7 +986,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, "not write it.", mft_no); atomic_dec(&ni->count); iput(vi); - return FALSE; + return false; } ntfs_debug("Managed to lock mft record 0x%lx, write it.", mft_no); @@ -995,7 +995,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, * return the locked ntfs inode. */ *locked_ni = ni; - return TRUE; + return true; } ntfs_debug("Inode 0x%lx is not in icache.", mft_no); /* The inode is not in icache. */ @@ -1003,13 +1003,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, if (!ntfs_is_mft_record(m->magic)) { ntfs_debug("Mft record 0x%lx is not a FILE record, write it.", mft_no); - return TRUE; + return true; } /* Write the mft record if it is a base inode. */ if (!m->base_mft_record) { ntfs_debug("Mft record 0x%lx is a base record, write it.", mft_no); - return TRUE; + return true; } /* * This is an extent mft record. Check if the inode corresponding to @@ -1033,7 +1033,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, */ ntfs_debug("Base inode 0x%lx is not in icache, write the " "extent record.", na.mft_no); - return TRUE; + return true; } ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no); /* @@ -1051,7 +1051,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, iput(vi); ntfs_debug("Base inode 0x%lx has no attached extent inodes, " "write the extent record.", na.mft_no); - return TRUE; + return true; } /* Iterate over the attached extent inodes. */ extent_nis = ni->ext.extent_ntfs_inos; @@ -1075,7 +1075,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, ntfs_debug("Extent inode 0x%lx is not attached to its base " "inode 0x%lx, write the extent record.", mft_no, na.mft_no); - return TRUE; + return true; } ntfs_debug("Extent inode 0x%lx is attached to its base inode 0x%lx.", mft_no, na.mft_no); @@ -1091,7 +1091,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, iput(vi); ntfs_debug("Extent mft record 0x%lx is already locked, do " "not write it.", mft_no); - return FALSE; + return false; } ntfs_debug("Managed to lock extent mft record 0x%lx, write it.", mft_no); @@ -1103,7 +1103,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, * the locked extent ntfs inode. */ *locked_ni = eni; - return TRUE; + return true; } static const char *es = " Leaving inconsistent metadata. Unmount and run " @@ -1354,7 +1354,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) ntfs_unmap_page(page); /* Allocate a cluster from the DATA_ZONE. */ rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE, - TRUE); + true); if (IS_ERR(rl2)) { up_write(&mftbmp_ni->runlist.lock); ntfs_error(vol->sb, "Failed to allocate a cluster for " @@ -1724,7 +1724,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) ATTR_RECORD *a = NULL; int ret, mp_size; u32 old_alen = 0; - BOOL mp_rebuilt = FALSE; + bool mp_rebuilt = false; ntfs_debug("Extending mft data allocation."); mft_ni = NTFS_I(vol->mft_ino); @@ -1780,7 +1780,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) old_last_vcn = rl[1].vcn; do { rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE, - TRUE); + true); if (likely(!IS_ERR(rl2))) break; if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { @@ -1884,7 +1884,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) ret = -EOPNOTSUPP; goto undo_alloc; } - mp_rebuilt = TRUE; + mp_rebuilt = true; /* Generate the mapping pairs array directly into the attr record. */ ret = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(a->data.non_resident.mapping_pairs_offset), @@ -2255,7 +2255,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, unsigned int ofs; int err; le16 seq_no, usn; - BOOL record_formatted = FALSE; + bool record_formatted = false; if (base_ni) { ntfs_debug("Entering (allocating an extent mft record for " @@ -2454,7 +2454,7 @@ have_alloc_rec: mft_ni->initialized_size = new_initialized_size; } write_unlock_irqrestore(&mft_ni->size_lock, flags); - record_formatted = TRUE; + record_formatted = true; /* Update the mft data attribute record to reflect the new sizes. */ m = map_mft_record(mft_ni); if (IS_ERR(m)) { diff --git a/fs/ntfs/mft.h b/fs/ntfs/mft.h index 639cd1bab08..b52bf87b99d 100644 --- a/fs/ntfs/mft.h +++ b/fs/ntfs/mft.h @@ -111,7 +111,7 @@ static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync) return err; } -extern BOOL ntfs_may_write_mft_record(ntfs_volume *vol, +extern bool ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, const MFT_RECORD *m, ntfs_inode **locked_ni); diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h index ddd3d503097..a12847ae467 100644 --- a/fs/ntfs/ntfs.h +++ b/fs/ntfs/ntfs.h @@ -105,7 +105,7 @@ extern int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size); extern void post_write_mst_fixup(NTFS_RECORD *b); /* From fs/ntfs/unistr.c */ -extern BOOL ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, +extern bool ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, const ntfschar *upcase, const u32 upcase_size); diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c index d0ef4182147..d80e3315cab 100644 --- a/fs/ntfs/quota.c +++ b/fs/ntfs/quota.c @@ -31,10 +31,10 @@ * ntfs_mark_quotas_out_of_date - mark the quotas out of date on an ntfs volume * @vol: ntfs volume on which to mark the quotas out of date * - * Mark the quotas out of date on the ntfs volume @vol and return TRUE on - * success and FALSE on error. + * Mark the quotas out of date on the ntfs volume @vol and return 'true' on + * success and 'false' on error. */ -BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol) +bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol) { ntfs_index_context *ictx; QUOTA_CONTROL_ENTRY *qce; @@ -46,7 +46,7 @@ BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol) goto done; if (!vol->quota_ino || !vol->quota_q_ino) { ntfs_error(vol->sb, "Quota inodes are not open."); - return FALSE; + return false; } mutex_lock(&vol->quota_q_ino->i_mutex); ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino)); @@ -106,12 +106,12 @@ set_done: NVolSetQuotaOutOfDate(vol); done: ntfs_debug("Done."); - return TRUE; + return true; err_out: if (ictx) ntfs_index_ctx_put(ictx); mutex_unlock(&vol->quota_q_ino->i_mutex); - return FALSE; + return false; } #endif /* NTFS_RW */ diff --git a/fs/ntfs/quota.h b/fs/ntfs/quota.h index 40e4763aa22..4cbe5594c0b 100644 --- a/fs/ntfs/quota.h +++ b/fs/ntfs/quota.h @@ -28,7 +28,7 @@ #include "types.h" #include "volume.h" -extern BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol); +extern bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol); #endif /* NTFS_RW */ diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index eb52b801512..9afd72c7ad0 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c @@ -149,10 +149,10 @@ static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl, * * It is up to the caller to serialize access to the runlists @dst and @src. * - * Return: TRUE Success, the runlists can be merged. - * FALSE Failure, the runlists cannot be merged. + * Return: true Success, the runlists can be merged. + * false Failure, the runlists cannot be merged. */ -static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst, +static inline bool ntfs_are_rl_mergeable(runlist_element *dst, runlist_element *src) { BUG_ON(!dst); @@ -160,19 +160,19 @@ static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst, /* We can merge unmapped regions even if they are misaligned. */ if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED)) - return TRUE; + return true; /* If the runs are misaligned, we cannot merge them. */ if ((dst->vcn + dst->length) != src->vcn) - return FALSE; + return false; /* If both runs are non-sparse and contiguous, we can merge them. */ if ((dst->lcn >= 0) && (src->lcn >= 0) && ((dst->lcn + dst->length) == src->lcn)) - return TRUE; + return true; /* If we are merging two holes, we can merge them. */ if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE)) - return TRUE; + return true; /* Cannot merge. */ - return FALSE; + return false; } /** @@ -218,7 +218,7 @@ static inline void __ntfs_rl_merge(runlist_element *dst, runlist_element *src) static inline runlist_element *ntfs_rl_append(runlist_element *dst, int dsize, runlist_element *src, int ssize, int loc) { - BOOL right = FALSE; /* Right end of @src needs merging. */ + bool right = false; /* Right end of @src needs merging. */ int marker; /* End of the inserted runs. */ BUG_ON(!dst); @@ -285,8 +285,8 @@ static inline runlist_element *ntfs_rl_append(runlist_element *dst, static inline runlist_element *ntfs_rl_insert(runlist_element *dst, int dsize, runlist_element *src, int ssize, int loc) { - BOOL left = FALSE; /* Left end of @src needs merging. */ - BOOL disc = FALSE; /* Discontinuity between @dst and @src. */ + bool left = false; /* Left end of @src needs merging. */ + bool disc = false; /* Discontinuity between @dst and @src. */ int marker; /* End of the inserted runs. */ BUG_ON(!dst); @@ -382,8 +382,8 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize, runlist_element *src, int ssize, int loc) { signed delta; - BOOL left = FALSE; /* Left end of @src needs merging. */ - BOOL right = FALSE; /* Right end of @src needs merging. */ + bool left = false; /* Left end of @src needs merging. */ + bool right = false; /* Right end of @src needs merging. */ int tail; /* Start of tail of @dst. */ int marker; /* End of the inserted runs. */ @@ -620,8 +620,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl, ; { - BOOL start; - BOOL finish; + bool start; + bool finish; int ds = dend + 1; /* Number of elements in drl & srl */ int ss = sfinal - sstart + 1; @@ -635,7 +635,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl, if (finish && !drl[dins].length) ss++; if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn)) - finish = FALSE; + finish = false; #if 0 ntfs_debug("dfinal = %i, dend = %i", dfinal, dend); ntfs_debug("sstart = %i, sfinal = %i, send = %i", sstart, sfinal, send); @@ -1134,7 +1134,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, { LCN prev_lcn; int rls; - BOOL the_end = FALSE; + bool the_end = false; BUG_ON(first_vcn < 0); BUG_ON(last_vcn < -1); @@ -1168,7 +1168,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } delta = first_vcn - rl->vcn; /* Header byte + length. */ @@ -1204,7 +1204,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } /* Header byte + length. */ rls += 1 + ntfs_get_nr_significant_bytes(length); @@ -1327,7 +1327,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, LCN prev_lcn; s8 *dst_max, *dst_next; int err = -ENOSPC; - BOOL the_end = FALSE; + bool the_end = false; s8 len_len, lcn_len; BUG_ON(first_vcn < 0); @@ -1370,7 +1370,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } delta = first_vcn - rl->vcn; /* Write length. */ @@ -1422,7 +1422,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } /* Write length. */ len_len = ntfs_write_significant_bytes(dst + 1, dst_max, @@ -1541,7 +1541,7 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist, */ if (rl->length) { runlist_element *trl; - BOOL is_end; + bool is_end; ntfs_debug("Shrinking runlist."); /* Determine the runlist size. */ @@ -1555,11 +1555,11 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist, * If a run was partially truncated, make the following runlist * element a terminator. */ - is_end = FALSE; + is_end = false; if (rl->length) { rl++; if (!rl->length) - is_end = TRUE; + is_end = true; rl->vcn = new_length; rl->length = 0; } @@ -1648,7 +1648,7 @@ int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist, s64 delta; runlist_element *rl, *rl_end, *rl_real_end, *trl; int old_size; - BOOL lcn_fixup = FALSE; + bool lcn_fixup = false; ntfs_debug("Entering for start 0x%llx, length 0x%llx.", (long long)start, (long long)length); @@ -1862,7 +1862,7 @@ split_end: if (rl->lcn >= 0) { rl->lcn -= delta; /* Need this in case the lcn just became negative. */ - lcn_fixup = TRUE; + lcn_fixup = true; } rl->length += delta; goto split_end; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 6b2712f10dd..03a391ac714 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -74,18 +74,18 @@ const option_t on_errors_arr[] = { * * Copied from old ntfs driver (which copied from vfat driver). */ -static int simple_getbool(char *s, BOOL *setval) +static int simple_getbool(char *s, bool *setval) { if (s) { if (!strcmp(s, "1") || !strcmp(s, "yes") || !strcmp(s, "true")) - *setval = TRUE; + *setval = true; else if (!strcmp(s, "0") || !strcmp(s, "no") || !strcmp(s, "false")) - *setval = FALSE; + *setval = false; else return 0; } else - *setval = TRUE; + *setval = true; return 1; } @@ -96,7 +96,7 @@ static int simple_getbool(char *s, BOOL *setval) * * Parse the recognized options in @opt for the ntfs volume described by @vol. */ -static BOOL parse_options(ntfs_volume *vol, char *opt) +static bool parse_options(ntfs_volume *vol, char *opt) { char *p, *v, *ov; static char *utf8 = "utf8"; @@ -137,7 +137,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt) } #define NTFS_GETOPT_BOOL(option, variable) \ if (!strcmp(p, option)) { \ - BOOL val; \ + bool val; \ if (!simple_getbool(v, &val)) \ goto needs_bool; \ variable = val; \ @@ -170,7 +170,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt) else NTFS_GETOPT_OCTAL("fmask", fmask) else NTFS_GETOPT_OCTAL("dmask", dmask) else NTFS_GETOPT("mft_zone_multiplier", mft_zone_multiplier) - else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE) + else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, true) else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files) else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive) else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse) @@ -194,7 +194,7 @@ use_utf8: if (!old_nls) { ntfs_error(vol->sb, "NLS character set " "%s not found.", v); - return FALSE; + return false; } ntfs_error(vol->sb, "NLS character set %s not " "found. Using previous one %s.", @@ -205,14 +205,14 @@ use_utf8: unload_nls(old_nls); } } else if (!strcmp(p, "utf8")) { - BOOL val = FALSE; + bool val = false; ntfs_warning(vol->sb, "Option utf8 is no longer " "supported, using option nls=utf8. Please " "use option nls=utf8 in the future and " "make sure utf8 is compiled either as a " "module or into the kernel."); if (!v || !*v) - val = TRUE; + val = true; else if (!simple_getbool(v, &val)) goto needs_bool; if (val) { @@ -231,7 +231,7 @@ use_utf8: } no_mount_options: if (errors && !sloppy) - return FALSE; + return false; if (sloppy) ntfs_warning(vol->sb, "Sloppy option given. Ignoring " "unrecognized mount option(s) and continuing."); @@ -240,14 +240,14 @@ no_mount_options: if (!on_errors) { ntfs_error(vol->sb, "Invalid errors option argument " "or bug in options parser."); - return FALSE; + return false; } } if (nls_map) { if (vol->nls_map && vol->nls_map != nls_map) { ntfs_error(vol->sb, "Cannot change NLS character set " "on remount."); - return FALSE; + return false; } /* else (!vol->nls_map) */ ntfs_debug("Using NLS character set %s.", nls_map->charset); vol->nls_map = nls_map; @@ -257,7 +257,7 @@ no_mount_options: if (!vol->nls_map) { ntfs_error(vol->sb, "Failed to load default " "NLS character set."); - return FALSE; + return false; } ntfs_debug("Using default NLS character set (%s).", vol->nls_map->charset); @@ -268,7 +268,7 @@ no_mount_options: mft_zone_multiplier) { ntfs_error(vol->sb, "Cannot change mft_zone_multiplier " "on remount."); - return FALSE; + return false; } if (mft_zone_multiplier < 1 || mft_zone_multiplier > 4) { ntfs_error(vol->sb, "Invalid mft_zone_multiplier. " @@ -318,16 +318,16 @@ no_mount_options: NVolSetSparseEnabled(vol); } } - return TRUE; + return true; needs_arg: ntfs_error(vol->sb, "The %s option requires an argument.", p); - return FALSE; + return false; needs_bool: ntfs_error(vol->sb, "The %s option requires a boolean argument.", p); - return FALSE; + return false; needs_val: ntfs_error(vol->sb, "Invalid %s option argument: %s", p, ov); - return FALSE; + return false; } #ifdef NTFS_RW @@ -543,16 +543,16 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) * is_boot_sector_ntfs - check whether a boot sector is a valid NTFS boot sector * @sb: Super block of the device to which @b belongs. * @b: Boot sector of device @sb to check. - * @silent: If TRUE, all output will be silenced. + * @silent: If 'true', all output will be silenced. * * is_boot_sector_ntfs() checks whether the boot sector @b is a valid NTFS boot - * sector. Returns TRUE if it is valid and FALSE if not. + * sector. Returns 'true' if it is valid and 'false' if not. * * @sb is only needed for warning/error output, i.e. it can be NULL when silent - * is TRUE. + * is 'true'. */ -static BOOL is_boot_sector_ntfs(const struct super_block *sb, - const NTFS_BOOT_SECTOR *b, const BOOL silent) +static bool is_boot_sector_ntfs(const struct super_block *sb, + const NTFS_BOOT_SECTOR *b, const bool silent) { /* * Check that checksum == sum of u32 values from b to the checksum @@ -620,9 +620,9 @@ static BOOL is_boot_sector_ntfs(const struct super_block *sb, */ if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55)) ntfs_warning(sb, "Invalid end of sector marker."); - return TRUE; + return true; not_ntfs: - return FALSE; + return false; } /** @@ -732,9 +732,9 @@ hotfix_primary_boot_sector: * @b: boot sector to parse * * Parse the ntfs boot sector @b and store all imporant information therein in - * the ntfs super block @vol. Return TRUE on success and FALSE on error. + * the ntfs super block @vol. Return 'true' on success and 'false' on error. */ -static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) +static bool parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) { unsigned int sectors_per_cluster_bits, nr_hidden_sects; int clusters_per_mft_record, clusters_per_index_record; @@ -751,7 +751,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "device block size (%lu). This is not " "supported. Sorry.", vol->sector_size, vol->sb->s_blocksize); - return FALSE; + return false; } ntfs_debug("sectors_per_cluster = 0x%x", b->bpb.sectors_per_cluster); sectors_per_cluster_bits = ffs(b->bpb.sectors_per_cluster) - 1; @@ -770,7 +770,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ntfs_error(vol->sb, "Cluster size (%i) is smaller than the " "sector size (%i). This is not supported. " "Sorry.", vol->cluster_size, vol->sector_size); - return FALSE; + return false; } clusters_per_mft_record = b->clusters_per_mft_record; ntfs_debug("clusters_per_mft_record = %i (0x%x)", @@ -802,7 +802,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "PAGE_CACHE_SIZE on your system (%lu). " "This is not supported. Sorry.", vol->mft_record_size, PAGE_CACHE_SIZE); - return FALSE; + return false; } /* We cannot support mft record sizes below the sector size. */ if (vol->mft_record_size < vol->sector_size) { @@ -810,7 +810,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "sector size (%i). This is not supported. " "Sorry.", vol->mft_record_size, vol->sector_size); - return FALSE; + return false; } clusters_per_index_record = b->clusters_per_index_record; ntfs_debug("clusters_per_index_record = %i (0x%x)", @@ -841,7 +841,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "the sector size (%i). This is not " "supported. Sorry.", vol->index_record_size, vol->sector_size); - return FALSE; + return false; } /* * Get the size of the volume in clusters and check for 64-bit-ness. @@ -851,7 +851,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ll = sle64_to_cpu(b->number_of_sectors) >> sectors_per_cluster_bits; if ((u64)ll >= 1ULL << 32) { ntfs_error(vol->sb, "Cannot handle 64-bit clusters. Sorry."); - return FALSE; + return false; } vol->nr_clusters = ll; ntfs_debug("vol->nr_clusters = 0x%llx", (long long)vol->nr_clusters); @@ -867,7 +867,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "Maximum supported is 2TiB. Sorry.", (unsigned long long)ll >> (40 - vol->cluster_size_bits)); - return FALSE; + return false; } } ll = sle64_to_cpu(b->mft_lcn); @@ -875,7 +875,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ntfs_error(vol->sb, "MFT LCN (%lli, 0x%llx) is beyond end of " "volume. Weird.", (unsigned long long)ll, (unsigned long long)ll); - return FALSE; + return false; } vol->mft_lcn = ll; ntfs_debug("vol->mft_lcn = 0x%llx", (long long)vol->mft_lcn); @@ -884,7 +884,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ntfs_error(vol->sb, "MFTMirr LCN (%lli, 0x%llx) is beyond end " "of volume. Weird.", (unsigned long long)ll, (unsigned long long)ll); - return FALSE; + return false; } vol->mftmirr_lcn = ll; ntfs_debug("vol->mftmirr_lcn = 0x%llx", (long long)vol->mftmirr_lcn); @@ -907,7 +907,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) vol->serial_no = le64_to_cpu(b->volume_serial_number); ntfs_debug("vol->serial_no = 0x%llx", (unsigned long long)vol->serial_no); - return TRUE; + return true; } /** @@ -1000,9 +1000,9 @@ static void ntfs_setup_allocators(ntfs_volume *vol) * load_and_init_mft_mirror - load and setup the mft mirror inode for a volume * @vol: ntfs super block describing device whose mft mirror to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_init_mft_mirror(ntfs_volume *vol) +static bool load_and_init_mft_mirror(ntfs_volume *vol) { struct inode *tmp_ino; ntfs_inode *tmp_ni; @@ -1014,7 +1014,7 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) if (!IS_ERR(tmp_ino)) iput(tmp_ino); /* Caller will display error message. */ - return FALSE; + return false; } /* * Re-initialize some specifics about $MFTMirr's inode as @@ -1041,20 +1041,20 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) tmp_ni->itype.index.block_size_bits = vol->mft_record_size_bits; vol->mftmirr_ino = tmp_ino; ntfs_debug("Done."); - return TRUE; + return true; } /** * check_mft_mirror - compare contents of the mft mirror with the mft * @vol: ntfs super block describing device whose mft mirror to check * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. * * Note, this function also results in the mft mirror runlist being completely * mapped into memory. The mft mirror write code requires this and will BUG() * should it find an unmapped runlist element. */ -static BOOL check_mft_mirror(ntfs_volume *vol) +static bool check_mft_mirror(ntfs_volume *vol) { struct super_block *sb = vol->sb; ntfs_inode *mirr_ni; @@ -1086,7 +1086,7 @@ static BOOL check_mft_mirror(ntfs_volume *vol) index); if (IS_ERR(mft_page)) { ntfs_error(sb, "Failed to read $MFT."); - return FALSE; + return false; } kmft = page_address(mft_page); /* Get the $MFTMirr page. */ @@ -1110,7 +1110,7 @@ mm_unmap_out: ntfs_unmap_page(mirr_page); mft_unmap_out: ntfs_unmap_page(mft_page); - return FALSE; + return false; } } /* Do not check the mirror record if it is not in use. */ @@ -1169,21 +1169,21 @@ mft_unmap_out: ntfs_error(sb, "$MFTMirr location mismatch. " "Run chkdsk."); up_read(&mirr_ni->runlist.lock); - return FALSE; + return false; } } while (rl2[i++].length); up_read(&mirr_ni->runlist.lock); ntfs_debug("Done."); - return TRUE; + return true; } /** * load_and_check_logfile - load and check the logfile inode for a volume * @vol: ntfs super block describing device whose logfile to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_check_logfile(ntfs_volume *vol, +static bool load_and_check_logfile(ntfs_volume *vol, RESTART_PAGE_HEADER **rp) { struct inode *tmp_ino; @@ -1194,17 +1194,17 @@ static BOOL load_and_check_logfile(ntfs_volume *vol, if (!IS_ERR(tmp_ino)) iput(tmp_ino); /* Caller will display error message. */ - return FALSE; + return false; } if (!ntfs_check_logfile(tmp_ino, rp)) { iput(tmp_ino); /* ntfs_check_logfile() will have displayed error output. */ - return FALSE; + return false; } NInoSetSparseDisabled(NTFS_I(tmp_ino)); vol->logfile_ino = tmp_ino; ntfs_debug("Done."); - return TRUE; + return true; } #define NTFS_HIBERFIL_HEADER_SIZE 4096 @@ -1329,10 +1329,10 @@ iput_out: * load_and_init_quota - load and setup the quota file for a volume if present * @vol: ntfs super block describing device whose quota file to load * - * Return TRUE on success or FALSE on error. If $Quota is not present, we + * Return 'true' on success or 'false' on error. If $Quota is not present, we * leave vol->quota_ino as NULL and return success. */ -static BOOL load_and_init_quota(ntfs_volume *vol) +static bool load_and_init_quota(ntfs_volume *vol) { MFT_REF mref; struct inode *tmp_ino; @@ -1366,11 +1366,11 @@ static BOOL load_and_init_quota(ntfs_volume *vol) * not enabled. */ NVolSetQuotaOutOfDate(vol); - return TRUE; + return true; } /* A real error occured. */ ntfs_error(vol->sb, "Failed to find inode number for $Quota."); - return FALSE; + return false; } /* We do not care for the type of match that was found. */ kfree(name); @@ -1380,25 +1380,25 @@ static BOOL load_and_init_quota(ntfs_volume *vol) if (!IS_ERR(tmp_ino)) iput(tmp_ino); ntfs_error(vol->sb, "Failed to load $Quota."); - return FALSE; + return false; } vol->quota_ino = tmp_ino; /* Get the $Q index allocation attribute. */ tmp_ino = ntfs_index_iget(vol->quota_ino, Q, 2); if (IS_ERR(tmp_ino)) { ntfs_error(vol->sb, "Failed to load $Quota/$Q index."); - return FALSE; + return false; } vol->quota_q_ino = tmp_ino; ntfs_debug("Done."); - return TRUE; + return true; } /** * load_and_init_usnjrnl - load and setup the transaction log if present * @vol: ntfs super block describing device whose usnjrnl file to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. * * If $UsnJrnl is not present or in the process of being disabled, we set * NVolUsnJrnlStamped() and return success. @@ -1408,7 +1408,7 @@ static BOOL load_and_init_quota(ntfs_volume *vol) * stamped and nothing has been logged since, we also set NVolUsnJrnlStamped() * and return success. */ -static BOOL load_and_init_usnjrnl(ntfs_volume *vol) +static bool load_and_init_usnjrnl(ntfs_volume *vol) { MFT_REF mref; struct inode *tmp_ino; @@ -1450,12 +1450,12 @@ not_enabled: * transaction logging is not enabled. */ NVolSetUsnJrnlStamped(vol); - return TRUE; + return true; } /* A real error occured. */ ntfs_error(vol->sb, "Failed to find inode number for " "$UsnJrnl."); - return FALSE; + return false; } /* We do not care for the type of match that was found. */ kfree(name); @@ -1465,7 +1465,7 @@ not_enabled: if (!IS_ERR(tmp_ino)) iput(tmp_ino); ntfs_error(vol->sb, "Failed to load $UsnJrnl."); - return FALSE; + return false; } vol->usnjrnl_ino = tmp_ino; /* @@ -1483,7 +1483,7 @@ not_enabled: if (IS_ERR(tmp_ino)) { ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$Max " "attribute."); - return FALSE; + return false; } vol->usnjrnl_max_ino = tmp_ino; if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) { @@ -1491,14 +1491,14 @@ not_enabled: "attribute (size is 0x%llx but should be at " "least 0x%zx bytes).", i_size_read(tmp_ino), sizeof(USN_HEADER)); - return FALSE; + return false; } /* Get the $DATA/$J attribute. */ tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, J, 2); if (IS_ERR(tmp_ino)) { ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$J " "attribute."); - return FALSE; + return false; } vol->usnjrnl_j_ino = tmp_ino; /* Verify $J is non-resident and sparse. */ @@ -1506,14 +1506,14 @@ not_enabled: if (unlikely(!NInoNonResident(tmp_ni) || !NInoSparse(tmp_ni))) { ntfs_error(vol->sb, "$UsnJrnl/$DATA/$J attribute is resident " "and/or not sparse."); - return FALSE; + return false; } /* Read the USN_HEADER from $DATA/$Max. */ page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0); if (IS_ERR(page)) { ntfs_error(vol->sb, "Failed to read from $UsnJrnl/$DATA/$Max " "attribute."); - return FALSE; + return false; } uh = (USN_HEADER*)page_address(page); /* Sanity check the $Max. */ @@ -1524,7 +1524,7 @@ not_enabled: (long long)sle64_to_cpu(uh->allocation_delta), (long long)sle64_to_cpu(uh->maximum_size)); ntfs_unmap_page(page); - return FALSE; + return false; } /* * If the transaction log has been stamped and nothing has been written @@ -1548,20 +1548,20 @@ not_enabled: (long long)sle64_to_cpu(uh->lowest_valid_usn), i_size_read(vol->usnjrnl_j_ino)); ntfs_unmap_page(page); - return FALSE; + return false; } ntfs_unmap_page(page); ntfs_debug("Done."); - return TRUE; + return true; } /** * load_and_init_attrdef - load the attribute definitions table for a volume * @vol: ntfs super block describing device whose attrdef to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_init_attrdef(ntfs_volume *vol) +static bool load_and_init_attrdef(ntfs_volume *vol) { loff_t i_size; struct super_block *sb = vol->sb; @@ -1607,7 +1607,7 @@ read_partial_attrdef_page: vol->attrdef_size = i_size; ntfs_debug("Read %llu bytes from $AttrDef.", i_size); iput(ino); - return TRUE; + return true; free_iput_failed: ntfs_free(vol->attrdef); vol->attrdef = NULL; @@ -1615,7 +1615,7 @@ iput_failed: iput(ino); failed: ntfs_error(sb, "Failed to initialize attribute definition table."); - return FALSE; + return false; } #endif /* NTFS_RW */ @@ -1624,9 +1624,9 @@ failed: * load_and_init_upcase - load the upcase table for an ntfs volume * @vol: ntfs super block describing device whose upcase to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_init_upcase(ntfs_volume *vol) +static bool load_and_init_upcase(ntfs_volume *vol) { loff_t i_size; struct super_block *sb = vol->sb; @@ -1682,7 +1682,7 @@ read_partial_upcase_page: ntfs_debug("Using volume specified $UpCase since default is " "not present."); mutex_unlock(&ntfs_lock); - return TRUE; + return true; } max = default_upcase_len; if (max > vol->upcase_len) @@ -1698,12 +1698,12 @@ read_partial_upcase_page: mutex_unlock(&ntfs_lock); ntfs_debug("Volume specified $UpCase matches default. Using " "default."); - return TRUE; + return true; } mutex_unlock(&ntfs_lock); ntfs_debug("Using volume specified $UpCase since it does not match " "the default."); - return TRUE; + return true; iput_upcase_failed: iput(ino); ntfs_free(vol->upcase); @@ -1717,11 +1717,11 @@ upcase_failed: mutex_unlock(&ntfs_lock); ntfs_error(sb, "Failed to load $UpCase from the volume. Using " "default."); - return TRUE; + return true; } mutex_unlock(&ntfs_lock); ntfs_error(sb, "Failed to initialize upcase table."); - return FALSE; + return false; } /* @@ -1739,9 +1739,9 @@ static struct lock_class_key * Open the system files with normal access functions and complete setting up * the ntfs super block @vol. * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_system_files(ntfs_volume *vol) +static bool load_system_files(ntfs_volume *vol) { struct super_block *sb = vol->sb; MFT_RECORD *m; @@ -2067,7 +2067,7 @@ get_ctx_vol_failed: #endif /* NTFS_RW */ /* If on NTFS versions before 3.0, we are done. */ if (unlikely(vol->major_ver < 3)) - return TRUE; + return true; /* NTFS 3.0+ specific initialization. */ /* Get the security descriptors inode. */ vol->secure_ino = ntfs_iget(sb, FILE_Secure); @@ -2173,7 +2173,7 @@ get_ctx_vol_failed: NVolSetErrors(vol); } #endif /* NTFS_RW */ - return TRUE; + return true; #ifdef NTFS_RW iput_usnjrnl_err_out: if (vol->usnjrnl_j_ino) @@ -2229,7 +2229,7 @@ iput_mirr_err_out: if (vol->mftmirr_ino) iput(vol->mftmirr_ino); #endif /* NTFS_RW */ - return FALSE; + return false; } /** diff --git a/fs/ntfs/types.h b/fs/ntfs/types.h index 6e4a7e3343f..8c8053b6698 100644 --- a/fs/ntfs/types.h +++ b/fs/ntfs/types.h @@ -62,11 +62,6 @@ typedef s64 USN; typedef sle64 leUSN; typedef enum { - FALSE = 0, - TRUE = 1 -} BOOL; - -typedef enum { CASE_SENSITIVE = 0, IGNORE_CASE = 1, } IGNORE_CASE_BOOL; diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c index a1b572196fe..6a495f7369f 100644 --- a/fs/ntfs/unistr.c +++ b/fs/ntfs/unistr.c @@ -61,16 +61,16 @@ static const u8 legal_ansi_char_array[0x40] = { * @upcase: upcase table (only if @ic == IGNORE_CASE) * @upcase_size: length in Unicode characters of @upcase (if present) * - * Compare the names @s1 and @s2 and return TRUE (1) if the names are - * identical, or FALSE (0) if they are not identical. If @ic is IGNORE_CASE, + * Compare the names @s1 and @s2 and return 'true' (1) if the names are + * identical, or 'false' (0) if they are not identical. If @ic is IGNORE_CASE, * the @upcase table is used to performa a case insensitive comparison. */ -BOOL ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, +bool ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, const ntfschar *upcase, const u32 upcase_size) { if (s1_len != s2_len) - return FALSE; + return false; if (ic == CASE_SENSITIVE) return !ntfs_ucsncmp(s1, s2, s1_len); return !ntfs_ucsncasecmp(s1, s2, s1_len, upcase, upcase_size); diff --git a/fs/ntfs/usnjrnl.c b/fs/ntfs/usnjrnl.c index 77773240d13..b2bc0d55b03 100644 --- a/fs/ntfs/usnjrnl.c +++ b/fs/ntfs/usnjrnl.c @@ -39,12 +39,12 @@ * @vol: ntfs volume on which to stamp the transaction log * * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return - * TRUE on success and FALSE on error. + * 'true' on success and 'false' on error. * * This function assumes that the transaction log has already been loaded and * consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl(). */ -BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) +bool ntfs_stamp_usnjrnl(ntfs_volume *vol) { ntfs_debug("Entering."); if (likely(!NVolUsnJrnlStamped(vol))) { @@ -56,7 +56,7 @@ BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) if (IS_ERR(page)) { ntfs_error(vol->sb, "Failed to read from " "$UsnJrnl/$DATA/$Max attribute."); - return FALSE; + return false; } uh = (USN_HEADER*)page_address(page); stamp = get_current_ntfs_time(); @@ -78,7 +78,7 @@ BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) NVolSetUsnJrnlStamped(vol); } ntfs_debug("Done."); - return TRUE; + return true; } #endif /* NTFS_RW */ diff --git a/fs/ntfs/usnjrnl.h b/fs/ntfs/usnjrnl.h index ff988b0deb4..3a8af75351e 100644 --- a/fs/ntfs/usnjrnl.h +++ b/fs/ntfs/usnjrnl.h @@ -198,7 +198,7 @@ typedef struct { /* sizeof() = 60 (0x3c) bytes */ } __attribute__ ((__packed__)) USN_RECORD; -extern BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol); +extern bool ntfs_stamp_usnjrnl(ntfs_volume *vol); #endif /* NTFS_RW */ diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 0368c640218..16b8d1ba706 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c @@ -338,7 +338,7 @@ static struct inode *dlmfs_get_root_inode(struct super_block *sb) inode->i_blocks = 0; inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_nlink++; + inc_nlink(inode); inode->i_fop = &simple_dir_operations; inode->i_op = &dlmfs_root_inode_operations; @@ -395,7 +395,7 @@ static struct inode *dlmfs_get_inode(struct inode *parent, /* directory inodes start off with i_nlink == * 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; } @@ -449,7 +449,7 @@ static int dlmfs_mkdir(struct inode * dir, } ip->ip_dlm = dlm; - dir->i_nlink++; + inc_nlink(dir); d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2bbfa17090c..d9ba0a931a0 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -961,25 +961,23 @@ static inline int ocfs2_write_should_remove_suid(struct inode *inode) } static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, - const char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - struct iovec local_iov = { .iov_base = (void __user *)buf, - .iov_len = count }; int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; u32 clusters; struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; loff_t newsize, saved_pos; - mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, - (unsigned int)count, + mlog_entry("(0x%p, %u, '%.*s')\n", filp, + (unsigned int)nr_segs, filp->f_dentry->d_name.len, filp->f_dentry->d_name.name); /* happy write of zero bytes */ - if (count == 0) + if (iocb->ki_left == 0) return 0; if (!inode) { @@ -1048,7 +1046,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, } else { saved_pos = iocb->ki_pos; } - newsize = count + saved_pos; + newsize = iocb->ki_left + saved_pos; mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", (long long) saved_pos, (long long) newsize, @@ -1081,7 +1079,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, if (!clusters) break; - ret = ocfs2_extend_file(inode, NULL, newsize, count); + ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left); if (ret < 0) { if (ret != -ENOSPC) mlog_errno(ret); @@ -1098,7 +1096,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb); - ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); + ret = generic_file_aio_write_nolock(iocb, iov, nr_segs, iocb->ki_pos); /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); @@ -1132,16 +1130,16 @@ out: } static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, - char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { int ret = 0, rw_level = -1, have_alloc_sem = 0; struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; - mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, - (unsigned int)count, + mlog_entry("(0x%p, %u, '%.*s')\n", filp, + (unsigned int)nr_segs, filp->f_dentry->d_name.len, filp->f_dentry->d_name.name); @@ -1185,7 +1183,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, } ocfs2_meta_unlock(inode, 0); - ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); + ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); if (ret == -EINVAL) mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 849c3b4bb94..259155f0eb2 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -429,7 +429,7 @@ static int ocfs2_mknod(struct inode *dir, mlog_errno(status); goto leave; } - dir->i_nlink++; + inc_nlink(dir); } status = ocfs2_add_entry(handle, dentry, inode, @@ -730,7 +730,7 @@ static int ocfs2_link(struct dentry *old_dentry, goto bail; } - inode->i_nlink++; + inc_nlink(inode); inode->i_ctime = CURRENT_TIME; fe->i_links_count = cpu_to_le16(inode->i_nlink); fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); @@ -739,7 +739,7 @@ static int ocfs2_link(struct dentry *old_dentry, err = ocfs2_journal_dirty(handle, fe_bh); if (err < 0) { le16_add_cpu(&fe->i_links_count, -1); - inode->i_nlink--; + drop_nlink(inode); mlog_errno(err); goto bail; } @@ -749,7 +749,7 @@ static int ocfs2_link(struct dentry *old_dentry, parent_fe_bh, de_bh); if (err) { le16_add_cpu(&fe->i_links_count, -1); - inode->i_nlink--; + drop_nlink(inode); mlog_errno(err); goto bail; } @@ -795,11 +795,23 @@ static int ocfs2_remote_dentry_delete(struct dentry *dentry) return ret; } +static inline int inode_is_unlinkable(struct inode *inode) +{ + if (S_ISDIR(inode->i_mode)) { + if (inode->i_nlink == 2) + return 1; + return 0; + } + + if (inode->i_nlink == 1) + return 1; + return 0; +} + static int ocfs2_unlink(struct inode *dir, struct dentry *dentry) { int status; - unsigned int saved_nlink = 0; struct inode *inode = dentry->d_inode; struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); u64 blkno; @@ -874,16 +886,6 @@ static int ocfs2_unlink(struct inode *dir, } } - /* There are still a few steps left until we can consider the - * unlink to have succeeded. Save off nlink here before - * modification so we can set it back in case we hit an issue - * before commit. */ - saved_nlink = inode->i_nlink; - if (S_ISDIR(inode->i_mode)) - inode->i_nlink = 0; - else - inode->i_nlink--; - status = ocfs2_remote_dentry_delete(dentry); if (status < 0) { /* This vote should succeed under all normal @@ -892,7 +894,7 @@ static int ocfs2_unlink(struct inode *dir, goto leave; } - if (!inode->i_nlink) { + if (inode_is_unlinkable(inode)) { status = ocfs2_prepare_orphan_dir(osb, handle, inode, orphan_name, &orphan_entry_bh); @@ -919,7 +921,7 @@ static int ocfs2_unlink(struct inode *dir, fe = (struct ocfs2_dinode *) fe_bh->b_data; - if (!inode->i_nlink) { + if (inode_is_unlinkable(inode)) { status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, orphan_entry_bh); if (status < 0) { @@ -935,10 +937,10 @@ static int ocfs2_unlink(struct inode *dir, goto leave; } - /* We can set nlink on the dinode now. clear the saved version - * so that it doesn't get set later. */ + if (S_ISDIR(inode->i_mode)) + drop_nlink(inode); + drop_nlink(inode); fe->i_links_count = cpu_to_le16(inode->i_nlink); - saved_nlink = 0; status = ocfs2_journal_dirty(handle, fe_bh); if (status < 0) { @@ -947,19 +949,16 @@ static int ocfs2_unlink(struct inode *dir, } if (S_ISDIR(inode->i_mode)) { - dir->i_nlink--; + drop_nlink(dir); status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh); if (status < 0) { mlog_errno(status); - dir->i_nlink++; + inc_nlink(dir); } } leave: - if (status < 0 && saved_nlink) - inode->i_nlink = saved_nlink; - if (handle) ocfs2_commit_trans(handle); @@ -1382,7 +1381,7 @@ static int ocfs2_rename(struct inode *old_dir, if (new_inode) { new_inode->i_nlink--; } else { - new_dir->i_nlink++; + inc_nlink(new_dir); mark_inode_dirty(new_dir); } } diff --git a/fs/open.c b/fs/open.c index 304c1c7814c..89e0c237a63 100644 --- a/fs/open.c +++ b/fs/open.c @@ -6,7 +6,6 @@ #include <linux/string.h> #include <linux/mm.h> -#include <linux/utime.h> #include <linux/file.h> #include <linux/smp_lock.h> #include <linux/quotaops.h> @@ -29,8 +28,6 @@ #include <linux/rcupdate.h> #include <linux/audit.h> -#include <asm/unistd.h> - int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) { int retval = -ENODEV; @@ -353,137 +350,6 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) } #endif -#ifdef __ARCH_WANT_SYS_UTIME - -/* - * sys_utime() can be implemented in user-level using sys_utimes(). - * Is this for backwards compatibility? If so, why not move it - * into the appropriate arch directory (for those architectures that - * need it). - */ - -/* If times==NULL, set access and modification to current time, - * must be owner or have write permission. - * Else, update from *times, must be owner or super user. - */ -asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) -{ - int error; - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; - - error = user_path_walk(filename, &nd); - if (error) - goto out; - inode = nd.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; - - /* Don't worry, the checks are done in inode_change_ok() */ - newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; - if (times) { - error = -EPERM; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - goto dput_and_out; - - error = get_user(newattrs.ia_atime.tv_sec, ×->actime); - newattrs.ia_atime.tv_nsec = 0; - if (!error) - error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); - newattrs.ia_mtime.tv_nsec = 0; - if (error) - goto dput_and_out; - - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; - } else { - error = -EACCES; - if (IS_IMMUTABLE(inode)) - goto dput_and_out; - - if (current->fsuid != inode->i_uid && - (error = vfs_permission(&nd, MAY_WRITE)) != 0) - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); - error = notify_change(nd.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); -dput_and_out: - path_release(&nd); -out: - return error; -} - -#endif - -/* If times==NULL, set access and modification to current time, - * must be owner or have write permission. - * Else, update from *times, must be owner or super user. - */ -long do_utimes(int dfd, char __user *filename, struct timeval *times) -{ - int error; - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; - - error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); - - if (error) - goto out; - inode = nd.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; - - /* Don't worry, the checks are done in inode_change_ok() */ - newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; - if (times) { - error = -EPERM; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - goto dput_and_out; - - newattrs.ia_atime.tv_sec = times[0].tv_sec; - newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000; - newattrs.ia_mtime.tv_sec = times[1].tv_sec; - newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000; - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; - } else { - error = -EACCES; - if (IS_IMMUTABLE(inode)) - goto dput_and_out; - - if (current->fsuid != inode->i_uid && - (error = vfs_permission(&nd, MAY_WRITE)) != 0) - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); - error = notify_change(nd.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); -dput_and_out: - path_release(&nd); -out: - return error; -} - -asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) -{ - struct timeval times[2]; - - if (utimes && copy_from_user(×, utimes, sizeof(times))) - return -EFAULT; - return do_utimes(dfd, filename, utimes ? times : NULL); -} - -asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) -{ - return sys_futimesat(AT_FDCWD, filename, utimes); -} - - /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and @@ -520,15 +386,21 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) current->cap_effective = current->cap_permitted; res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); - if (!res) { - res = vfs_permission(&nd, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; - path_release(&nd); - } + if (res) + goto out; + res = vfs_permission(&nd, mode); + /* SuS v2 requires we report a read only fs too */ + if(res || !(mode & S_IWOTH) || + special_file(nd.dentry->d_inode->i_mode)) + goto out_path_release; + + if(IS_RDONLY(nd.dentry->d_inode)) + res = -EROFS; + +out_path_release: + path_release(&nd); +out: current->fsuid = old_fsuid; current->fsgid = old_fsgid; current->cap_effective = old_cap; @@ -737,10 +609,11 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) int error; error = user_path_walk(filename, &nd); - if (!error) { - error = chown_common(nd.dentry, user, group); - path_release(&nd); - } + if (error) + goto out; + error = chown_common(nd.dentry, user, group); + path_release(&nd); +out: return error; } @@ -756,10 +629,10 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; error = __user_walk_fd(dfd, filename, follow, &nd); - if (!error) { - error = chown_common(nd.dentry, user, group); - path_release(&nd); - } + if (error) + goto out; + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -770,10 +643,11 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group int error; error = user_path_walk_link(filename, &nd); - if (!error) { - error = chown_common(nd.dentry, user, group); - path_release(&nd); - } + if (error) + goto out; + error = chown_common(nd.dentry, user, group); + path_release(&nd); +out: return error; } @@ -782,15 +656,17 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) { struct file * file; int error = -EBADF; + struct dentry * dentry; file = fget(fd); - if (file) { - struct dentry * dentry; - dentry = file->f_dentry; - audit_inode(NULL, dentry->d_inode); - error = chown_common(dentry, user, group); - fput(file); - } + if (!file) + goto out; + + dentry = file->f_dentry; + audit_inode(NULL, dentry->d_inode); + error = chown_common(dentry, user, group); + fput(file); +out: return error; } diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index d713ce6b3e1..67e665fdb7f 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := check.o +obj-$(CONFIG_BLOCK) := check.o obj-$(CONFIG_ACORN_PARTITION) += acorn.o obj-$(CONFIG_AMIGA_PARTITION) += amiga.o diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c index 7ab1c11dca4..1a60926a4cc 100644 --- a/fs/partitions/ldm.c +++ b/fs/partitions/ldm.c @@ -30,11 +30,6 @@ #include "check.h" #include "msdos.h" -typedef enum { - FALSE = 0, - TRUE = 1 -} BOOL; - /** * ldm_debug/info/error/crit - Output an error message * @f: A printf format string containing the message @@ -103,24 +98,24 @@ static int ldm_parse_hexbyte (const u8 *src) * * N.B. The GUID need not be NULL terminated. * - * Return: TRUE @dest contains binary GUID - * FALSE @dest contents are undefined + * Return: 'true' @dest contains binary GUID + * 'false' @dest contents are undefined */ -static BOOL ldm_parse_guid (const u8 *src, u8 *dest) +static bool ldm_parse_guid (const u8 *src, u8 *dest) { static const int size[] = { 4, 2, 2, 2, 6 }; int i, j, v; if (src[8] != '-' || src[13] != '-' || src[18] != '-' || src[23] != '-') - return FALSE; + return false; for (j = 0; j < 5; j++, src++) for (i = 0; i < size[j]; i++, src+=2, *dest++ = v) if ((v = ldm_parse_hexbyte (src)) < 0) - return FALSE; + return false; - return TRUE; + return true; } @@ -132,17 +127,17 @@ static BOOL ldm_parse_guid (const u8 *src, u8 *dest) * This parses the LDM database PRIVHEAD structure supplied in @data and * sets up the in-memory privhead structure @ph with the obtained information. * - * Return: TRUE @ph contains the PRIVHEAD data - * FALSE @ph contents are undefined + * Return: 'true' @ph contains the PRIVHEAD data + * 'false' @ph contents are undefined */ -static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) +static bool ldm_parse_privhead (const u8 *data, struct privhead *ph) { BUG_ON (!data || !ph); if (MAGIC_PRIVHEAD != BE64 (data)) { ldm_error ("Cannot find PRIVHEAD structure. LDM database is" " corrupt. Aborting."); - return FALSE; + return false; } ph->ver_major = BE16 (data + 0x000C); @@ -155,7 +150,7 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) if ((ph->ver_major != 2) || (ph->ver_minor != 11)) { ldm_error ("Expected PRIVHEAD version %d.%d, got %d.%d." " Aborting.", 2, 11, ph->ver_major, ph->ver_minor); - return FALSE; + return false; } if (ph->config_size != LDM_DB_SIZE) { /* 1 MiB in sectors. */ /* Warn the user and continue, carefully */ @@ -166,16 +161,16 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) if ((ph->logical_disk_size == 0) || (ph->logical_disk_start + ph->logical_disk_size > ph->config_start)) { ldm_error ("PRIVHEAD disk size doesn't match real disk size"); - return FALSE; + return false; } if (!ldm_parse_guid (data + 0x0030, ph->disk_id)) { ldm_error ("PRIVHEAD contains an invalid GUID."); - return FALSE; + return false; } ldm_debug ("Parsed PRIVHEAD successfully."); - return TRUE; + return true; } /** @@ -189,16 +184,16 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) * * N.B. The *_start and *_size values returned in @toc are not range-checked. * - * Return: TRUE @toc contains the TOCBLOCK data - * FALSE @toc contents are undefined + * Return: 'true' @toc contains the TOCBLOCK data + * 'false' @toc contents are undefined */ -static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) +static bool ldm_parse_tocblock (const u8 *data, struct tocblock *toc) { BUG_ON (!data || !toc); if (MAGIC_TOCBLOCK != BE64 (data)) { ldm_crit ("Cannot find TOCBLOCK, database may be corrupt."); - return FALSE; + return false; } strncpy (toc->bitmap1_name, data + 0x24, sizeof (toc->bitmap1_name)); toc->bitmap1_name[sizeof (toc->bitmap1_name) - 1] = 0; @@ -209,7 +204,7 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) sizeof (toc->bitmap1_name)) != 0) { ldm_crit ("TOCBLOCK's first bitmap is '%s', should be '%s'.", TOC_BITMAP1, toc->bitmap1_name); - return FALSE; + return false; } strncpy (toc->bitmap2_name, data + 0x46, sizeof (toc->bitmap2_name)); toc->bitmap2_name[sizeof (toc->bitmap2_name) - 1] = 0; @@ -219,10 +214,10 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) sizeof (toc->bitmap2_name)) != 0) { ldm_crit ("TOCBLOCK's second bitmap is '%s', should be '%s'.", TOC_BITMAP2, toc->bitmap2_name); - return FALSE; + return false; } ldm_debug ("Parsed TOCBLOCK successfully."); - return TRUE; + return true; } /** @@ -235,16 +230,16 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) * * N.B. The *_start, *_size and *_seq values will be range-checked later. * - * Return: TRUE @vm contains VMDB info - * FALSE @vm contents are undefined + * Return: 'true' @vm contains VMDB info + * 'false' @vm contents are undefined */ -static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) +static bool ldm_parse_vmdb (const u8 *data, struct vmdb *vm) { BUG_ON (!data || !vm); if (MAGIC_VMDB != BE32 (data)) { ldm_crit ("Cannot find the VMDB, database may be corrupt."); - return FALSE; + return false; } vm->ver_major = BE16 (data + 0x12); @@ -252,7 +247,7 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) if ((vm->ver_major != 4) || (vm->ver_minor != 10)) { ldm_error ("Expected VMDB version %d.%d, got %d.%d. " "Aborting.", 4, 10, vm->ver_major, vm->ver_minor); - return FALSE; + return false; } vm->vblk_size = BE32 (data + 0x08); @@ -260,7 +255,7 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) vm->last_vblk_seq = BE32 (data + 0x04); ldm_debug ("Parsed VMDB successfully."); - return TRUE; + return true; } /** @@ -270,10 +265,10 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) * * This compares the two privhead structures @ph1 and @ph2. * - * Return: TRUE Identical - * FALSE Different + * Return: 'true' Identical + * 'false' Different */ -static BOOL ldm_compare_privheads (const struct privhead *ph1, +static bool ldm_compare_privheads (const struct privhead *ph1, const struct privhead *ph2) { BUG_ON (!ph1 || !ph2); @@ -294,10 +289,10 @@ static BOOL ldm_compare_privheads (const struct privhead *ph1, * * This compares the two tocblock structures @toc1 and @toc2. * - * Return: TRUE Identical - * FALSE Different + * Return: 'true' Identical + * 'false' Different */ -static BOOL ldm_compare_tocblocks (const struct tocblock *toc1, +static bool ldm_compare_tocblocks (const struct tocblock *toc1, const struct tocblock *toc2) { BUG_ON (!toc1 || !toc2); @@ -323,17 +318,17 @@ static BOOL ldm_compare_tocblocks (const struct tocblock *toc1, * the configuration area (the database). The values are range-checked against * @hd, which contains the real size of the disk. * - * Return: TRUE Success - * FALSE Error + * Return: 'true' Success + * 'false' Error */ -static BOOL ldm_validate_privheads (struct block_device *bdev, +static bool ldm_validate_privheads (struct block_device *bdev, struct privhead *ph1) { static const int off[3] = { OFF_PRIV1, OFF_PRIV2, OFF_PRIV3 }; struct privhead *ph[3] = { ph1 }; Sector sect; u8 *data; - BOOL result = FALSE; + bool result = false; long num_sects; int i; @@ -393,7 +388,7 @@ static BOOL ldm_validate_privheads (struct block_device *bdev, goto out; }*/ ldm_debug ("Validated PRIVHEADs successfully."); - result = TRUE; + result = true; out: kfree (ph[1]); kfree (ph[2]); @@ -411,10 +406,10 @@ out: * * The offsets and sizes of the configs are range-checked against a privhead. * - * Return: TRUE @toc1 contains validated TOCBLOCK info - * FALSE @toc1 contents are undefined + * Return: 'true' @toc1 contains validated TOCBLOCK info + * 'false' @toc1 contents are undefined */ -static BOOL ldm_validate_tocblocks (struct block_device *bdev, +static bool ldm_validate_tocblocks (struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { static const int off[4] = { OFF_TOCB1, OFF_TOCB2, OFF_TOCB3, OFF_TOCB4}; @@ -422,7 +417,7 @@ static BOOL ldm_validate_tocblocks (struct block_device *bdev, struct privhead *ph; Sector sect; u8 *data; - BOOL result = FALSE; + bool result = false; int i; BUG_ON (!bdev || !ldb); @@ -465,7 +460,7 @@ static BOOL ldm_validate_tocblocks (struct block_device *bdev, } ldm_debug ("Validated TOCBLOCKs successfully."); - result = TRUE; + result = true; out: kfree (tb[1]); kfree (tb[2]); @@ -482,15 +477,15 @@ out: * Find the vmdb of the LDM Database stored on @bdev and return the parsed * information in @ldb. * - * Return: TRUE @ldb contains validated VBDB info - * FALSE @ldb contents are undefined + * Return: 'true' @ldb contains validated VBDB info + * 'false' @ldb contents are undefined */ -static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base, +static bool ldm_validate_vmdb (struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { Sector sect; u8 *data; - BOOL result = FALSE; + bool result = false; struct vmdb *vm; struct tocblock *toc; @@ -502,7 +497,7 @@ static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base, data = read_dev_sector (bdev, base + OFF_VMDB, §); if (!data) { ldm_crit ("Disk read failed."); - return FALSE; + return false; } if (!ldm_parse_vmdb (data, vm)) @@ -527,7 +522,7 @@ static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base, goto out; } - result = TRUE; + result = true; out: put_dev_sector (sect); return result; @@ -547,23 +542,23 @@ out: * only likely to happen if the underlying device is strange. If that IS * the case we should return zero to let someone else try. * - * Return: TRUE @bdev is a dynamic disk - * FALSE @bdev is not a dynamic disk, or an error occurred + * Return: 'true' @bdev is a dynamic disk + * 'false' @bdev is not a dynamic disk, or an error occurred */ -static BOOL ldm_validate_partition_table (struct block_device *bdev) +static bool ldm_validate_partition_table (struct block_device *bdev) { Sector sect; u8 *data; struct partition *p; int i; - BOOL result = FALSE; + bool result = false; BUG_ON (!bdev); data = read_dev_sector (bdev, 0, §); if (!data) { ldm_crit ("Disk read failed."); - return FALSE; + return false; } if (*(__le16*) (data + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC)) @@ -572,7 +567,7 @@ static BOOL ldm_validate_partition_table (struct block_device *bdev) p = (struct partition*)(data + 0x01BE); for (i = 0; i < 4; i++, p++) if (SYS_IND (p) == WIN2K_DYNAMIC_PARTITION) { - result = TRUE; + result = true; break; } @@ -625,10 +620,10 @@ static struct vblk * ldm_get_disk_objid (const struct ldmdb *ldb) * N.B. This function creates the partitions in the order it finds partition * objects in the linked list. * - * Return: TRUE Partition created - * FALSE Error, probably a range checking problem + * Return: 'true' Partition created + * 'false' Error, probably a range checking problem */ -static BOOL ldm_create_data_partitions (struct parsed_partitions *pp, +static bool ldm_create_data_partitions (struct parsed_partitions *pp, const struct ldmdb *ldb) { struct list_head *item; @@ -642,7 +637,7 @@ static BOOL ldm_create_data_partitions (struct parsed_partitions *pp, disk = ldm_get_disk_objid (ldb); if (!disk) { ldm_crit ("Can't find the ID of this disk in the database."); - return FALSE; + return false; } printk (" [LDM]"); @@ -661,7 +656,7 @@ static BOOL ldm_create_data_partitions (struct parsed_partitions *pp, } printk ("\n"); - return TRUE; + return true; } @@ -766,10 +761,10 @@ static int ldm_get_vstr (const u8 *block, u8 *buffer, int buflen) * * Read a raw VBLK Component object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Component VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Component VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_vstate, r_child, r_parent, r_stripe, r_cols, len; struct vblk_comp *comp; @@ -792,11 +787,11 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) len = r_parent; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_CMP3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; comp = &vb->vblk.comp; ldm_get_vstr (buffer + 0x18 + r_name, comp->state, @@ -806,7 +801,7 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) comp->parent_id = ldm_get_vnum (buffer + 0x2D + r_child); comp->chunksize = r_stripe ? ldm_get_vnum (buffer+r_parent+0x2E) : 0; - return TRUE; + return true; } /** @@ -817,8 +812,8 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk Group object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Disk Group VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk Group VBLK + * 'false' @vb contents are not defined */ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb) { @@ -841,16 +836,16 @@ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb) len = r_diskid; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DGR3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; dgrp = &vb->vblk.dgrp; ldm_get_vstr (buffer + 0x18 + r_name, dgrp->disk_id, sizeof (dgrp->disk_id)); - return TRUE; + return true; } /** @@ -861,10 +856,10 @@ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk Group object (version 4) into a vblk structure. * - * Return: TRUE @vb contains a Disk Group VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk Group VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) { char buf[64]; int r_objid, r_name, r_id1, r_id2, len; @@ -885,16 +880,16 @@ static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) len = r_name; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DGR4; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; dgrp = &vb->vblk.dgrp; ldm_get_vstr (buffer + 0x18 + r_objid, buf, sizeof (buf)); - return TRUE; + return true; } /** @@ -905,10 +900,10 @@ static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Disk VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_diskid, r_altname, len; struct vblk_disk *disk; @@ -921,19 +916,19 @@ static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) r_altname = ldm_relative (buffer, buflen, 0x18, r_diskid); len = r_altname; if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DSK3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; disk = &vb->vblk.disk; ldm_get_vstr (buffer + 0x18 + r_diskid, disk->alt_name, sizeof (disk->alt_name)); if (!ldm_parse_guid (buffer + 0x19 + r_name, disk->disk_id)) - return FALSE; + return false; - return TRUE; + return true; } /** @@ -944,10 +939,10 @@ static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk object (version 4) into a vblk structure. * - * Return: TRUE @vb contains a Disk VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, len; struct vblk_disk *disk; @@ -958,15 +953,15 @@ static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) r_name = ldm_relative (buffer, buflen, 0x18, r_objid); len = r_name; if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DSK4; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; disk = &vb->vblk.disk; memcpy (disk->disk_id, buffer + 0x18 + r_name, GUID_SIZE); - return TRUE; + return true; } /** @@ -977,10 +972,10 @@ static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Partition object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Partition VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Partition VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_size, r_parent, r_diskid, r_index, len; struct vblk_part *part; @@ -1001,11 +996,11 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) len = r_diskid; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_PRT3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; part = &vb->vblk.part; part->start = BE64 (buffer + 0x24 + r_name); @@ -1018,7 +1013,7 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) else part->partnum = 0; - return TRUE; + return true; } /** @@ -1029,10 +1024,10 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Volume object (version 5) into a vblk structure. * - * Return: TRUE @vb contains a Volume VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Volume VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_vtype, r_child, r_size, r_id1, r_id2, r_size2; int r_drive, len; @@ -1068,11 +1063,11 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) len = r_drive; if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_VOL5; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; volu = &vb->vblk.volu; @@ -1087,7 +1082,7 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) ldm_get_vstr (buffer + 0x53 + r_size, volu->drive_hint, sizeof (volu->drive_hint)); } - return TRUE; + return true; } /** @@ -1100,12 +1095,12 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) * information common to all VBLK types, then delegates the rest of the work to * helper functions: ldm_parse_*. * - * Return: TRUE @vb contains a VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) +static bool ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) { - BOOL result = FALSE; + bool result = false; int r_objid; BUG_ON (!buf || !vb); @@ -1113,7 +1108,7 @@ static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) r_objid = ldm_relative (buf, len, 0x18, 0); if (r_objid < 0) { ldm_error ("VBLK header is corrupt."); - return FALSE; + return false; } vb->flags = buf[0x12]; @@ -1152,10 +1147,10 @@ static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) * * N.B. This function does not check the validity of the VBLKs. * - * Return: TRUE The VBLK was added - * FALSE An error occurred + * Return: 'true' The VBLK was added + * 'false' An error occurred */ -static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) +static bool ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) { struct vblk *vb; struct list_head *item; @@ -1165,12 +1160,12 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) vb = kmalloc (sizeof (*vb), GFP_KERNEL); if (!vb) { ldm_crit ("Out of memory."); - return FALSE; + return false; } if (!ldm_parse_vblk (data, len, vb)) { kfree(vb); - return FALSE; /* Already logged */ + return false; /* Already logged */ } /* Put vblk into the correct list. */ @@ -1196,13 +1191,13 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) if ((v->vblk.part.disk_id == vb->vblk.part.disk_id) && (v->vblk.part.start > vb->vblk.part.start)) { list_add_tail (&vb->list, &v->list); - return TRUE; + return true; } } list_add_tail (&vb->list, &ldb->v_part); break; } - return TRUE; + return true; } /** @@ -1214,10 +1209,10 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) * Fragmented VBLKs may not be consecutive in the database, so they are placed * in a list so they can be pieced together later. * - * Return: TRUE Success, the VBLK was added to the list - * FALSE Error, a problem occurred + * Return: 'true' Success, the VBLK was added to the list + * 'false' Error, a problem occurred */ -static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags) +static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) { struct frag *f; struct list_head *item; @@ -1230,7 +1225,7 @@ static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags) num = BE16 (data + 0x0E); if ((num < 1) || (num > 4)) { ldm_error ("A VBLK claims to have %d parts.", num); - return FALSE; + return false; } list_for_each (item, frags) { @@ -1242,7 +1237,7 @@ static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags) f = kmalloc (sizeof (*f) + size*num, GFP_KERNEL); if (!f) { ldm_crit ("Out of memory."); - return FALSE; + return false; } f->group = group; @@ -1255,7 +1250,7 @@ found: if (f->map & (1 << rec)) { ldm_error ("Duplicate VBLK, part %d.", rec); f->map &= 0x7F; /* Mark the group as broken */ - return FALSE; + return false; } f->map |= (1 << rec); @@ -1266,7 +1261,7 @@ found: } memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size); - return TRUE; + return true; } /** @@ -1295,10 +1290,10 @@ static void ldm_frag_free (struct list_head *list) * Now that all the fragmented VBLKs have been collected, they must be added to * the database for later use. * - * Return: TRUE All the fragments we added successfully - * FALSE One or more of the fragments we invalid + * Return: 'true' All the fragments we added successfully + * 'false' One or more of the fragments we invalid */ -static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) +static bool ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) { struct frag *f; struct list_head *item; @@ -1311,13 +1306,13 @@ static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) if (f->map != 0xFF) { ldm_error ("VBLK group %d is incomplete (0x%02x).", f->group, f->map); - return FALSE; + return false; } if (!ldm_ldmdb_add (f->data, f->num*ldb->vm.vblk_size, ldb)) - return FALSE; /* Already logged */ + return false; /* Already logged */ } - return TRUE; + return true; } /** @@ -1329,16 +1324,16 @@ static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) * To use the information from the VBLKs, they need to be read from the disk, * unpacked and validated. We cache them in @ldb according to their type. * - * Return: TRUE All the VBLKs were read successfully - * FALSE An error occurred + * Return: 'true' All the VBLKs were read successfully + * 'false' An error occurred */ -static BOOL ldm_get_vblks (struct block_device *bdev, unsigned long base, +static bool ldm_get_vblks (struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { int size, perbuf, skip, finish, s, v, recs; u8 *data = NULL; Sector sect; - BOOL result = FALSE; + bool result = false; LIST_HEAD (frags); BUG_ON (!bdev || !ldb); diff --git a/fs/pipe.c b/fs/pipe.c index f3b6f71e9d0..b1626f269a3 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -218,9 +218,10 @@ static struct pipe_buf_operations anon_pipe_buf_ops = { }; static ssize_t -pipe_readv(struct file *filp, const struct iovec *_iov, - unsigned long nr_segs, loff_t *ppos) +pipe_read(struct kiocb *iocb, const struct iovec *_iov, + unsigned long nr_segs, loff_t pos) { + struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; struct pipe_inode_info *pipe; int do_wakeup; @@ -330,17 +331,10 @@ redo: } static ssize_t -pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) -{ - struct iovec iov = { .iov_base = buf, .iov_len = count }; - - return pipe_readv(filp, &iov, 1, ppos); -} - -static ssize_t -pipe_writev(struct file *filp, const struct iovec *_iov, - unsigned long nr_segs, loff_t *ppos) +pipe_write(struct kiocb *iocb, const struct iovec *_iov, + unsigned long nr_segs, loff_t ppos) { + struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; struct pipe_inode_info *pipe; ssize_t ret; @@ -510,15 +504,6 @@ out: } static ssize_t -pipe_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; - - return pipe_writev(filp, &iov, 1, ppos); -} - -static ssize_t bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { return -EBADF; @@ -736,8 +721,8 @@ pipe_rdwr_open(struct inode *inode, struct file *filp) */ const struct file_operations read_fifo_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, + .read = do_sync_read, + .aio_read = pipe_read, .write = bad_pipe_w, .poll = pipe_poll, .ioctl = pipe_ioctl, @@ -749,8 +734,8 @@ const struct file_operations read_fifo_fops = { const struct file_operations write_fifo_fops = { .llseek = no_llseek, .read = bad_pipe_r, - .write = pipe_write, - .writev = pipe_writev, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_write_open, @@ -760,10 +745,10 @@ const struct file_operations write_fifo_fops = { const struct file_operations rdwr_fifo_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, - .write = pipe_write, - .writev = pipe_writev, + .read = do_sync_read, + .aio_read = pipe_read, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_rdwr_open, @@ -773,8 +758,8 @@ const struct file_operations rdwr_fifo_fops = { static struct file_operations read_pipe_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, + .read = do_sync_read, + .aio_read = pipe_read, .write = bad_pipe_w, .poll = pipe_poll, .ioctl = pipe_ioctl, @@ -786,8 +771,8 @@ static struct file_operations read_pipe_fops = { static struct file_operations write_pipe_fops = { .llseek = no_llseek, .read = bad_pipe_r, - .write = pipe_write, - .writev = pipe_writev, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_write_open, @@ -797,10 +782,10 @@ static struct file_operations write_pipe_fops = { static struct file_operations rdwr_pipe_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, - .write = pipe_write, - .writev = pipe_writev, + .read = do_sync_read, + .aio_read = pipe_read, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_rdwr_open, @@ -889,87 +874,118 @@ fail_inode: return NULL; } -int do_pipe(int *fd) +struct file *create_write_pipe(void) { - struct qstr this; - char name[32]; + int err; + struct inode *inode; + struct file *f; struct dentry *dentry; - struct inode * inode; - struct file *f1, *f2; - int error; - int i, j; - - error = -ENFILE; - f1 = get_empty_filp(); - if (!f1) - goto no_files; - - f2 = get_empty_filp(); - if (!f2) - goto close_f1; + char name[32]; + struct qstr this; + f = get_empty_filp(); + if (!f) + return ERR_PTR(-ENFILE); + err = -ENFILE; inode = get_pipe_inode(); if (!inode) - goto close_f12; - - error = get_unused_fd(); - if (error < 0) - goto close_f12_inode; - i = error; - - error = get_unused_fd(); - if (error < 0) - goto close_f12_inode_i; - j = error; + goto err_file; - error = -ENOMEM; sprintf(name, "[%lu]", inode->i_ino); this.name = name; this.len = strlen(name); this.hash = inode->i_ino; /* will go */ + err = -ENOMEM; dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); if (!dentry) - goto close_f12_inode_i_j; + goto err_inode; dentry->d_op = &pipefs_dentry_operations; d_add(dentry, inode); - f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); - f1->f_dentry = f2->f_dentry = dget(dentry); - f1->f_mapping = f2->f_mapping = inode->i_mapping; - - /* read file */ - f1->f_pos = f2->f_pos = 0; - f1->f_flags = O_RDONLY; - f1->f_op = &read_pipe_fops; - f1->f_mode = FMODE_READ; - f1->f_version = 0; - - /* write file */ - f2->f_flags = O_WRONLY; - f2->f_op = &write_pipe_fops; - f2->f_mode = FMODE_WRITE; - f2->f_version = 0; - - fd_install(i, f1); - fd_install(j, f2); - fd[0] = i; - fd[1] = j; + f->f_vfsmnt = mntget(pipe_mnt); + f->f_dentry = dentry; + f->f_mapping = inode->i_mapping; - return 0; + f->f_flags = O_WRONLY; + f->f_op = &write_pipe_fops; + f->f_mode = FMODE_WRITE; + f->f_version = 0; + + return f; -close_f12_inode_i_j: - put_unused_fd(j); -close_f12_inode_i: - put_unused_fd(i); -close_f12_inode: + err_inode: free_pipe_info(inode); iput(inode); -close_f12: - put_filp(f2); -close_f1: - put_filp(f1); -no_files: - return error; + err_file: + put_filp(f); + return ERR_PTR(err); +} + +void free_write_pipe(struct file *f) +{ + mntput(f->f_vfsmnt); + dput(f->f_dentry); + put_filp(f); +} + +struct file *create_read_pipe(struct file *wrf) +{ + struct file *f = get_empty_filp(); + if (!f) + return ERR_PTR(-ENFILE); + + /* Grab pipe from the writer */ + f->f_vfsmnt = mntget(wrf->f_vfsmnt); + f->f_dentry = dget(wrf->f_dentry); + f->f_mapping = wrf->f_dentry->d_inode->i_mapping; + + f->f_pos = 0; + f->f_flags = O_RDONLY; + f->f_op = &read_pipe_fops; + f->f_mode = FMODE_READ; + f->f_version = 0; + + return f; +} + +int do_pipe(int *fd) +{ + struct file *fw, *fr; + int error; + int fdw, fdr; + + fw = create_write_pipe(); + if (IS_ERR(fw)) + return PTR_ERR(fw); + fr = create_read_pipe(fw); + error = PTR_ERR(fr); + if (IS_ERR(fr)) + goto err_write_pipe; + + error = get_unused_fd(); + if (error < 0) + goto err_read_pipe; + fdr = error; + + error = get_unused_fd(); + if (error < 0) + goto err_fdr; + fdw = error; + + fd_install(fdr, fr); + fd_install(fdw, fw); + fd[0] = fdr; + fd[1] = fdw; + + return 0; + + err_fdr: + put_unused_fd(fdr); + err_read_pipe: + put_filp(fr); + err_write_pipe: + free_write_pipe(fw); + return error; } /* diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 6c8dcf7613f..aec931e0997 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -58,11 +58,9 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) if (acl) { int size = sizeof(struct posix_acl) + acl->a_count * sizeof(struct posix_acl_entry); - clone = kmalloc(size, flags); - if (clone) { - memcpy(clone, acl, size); + clone = kmemdup(acl, size, flags); + if (clone) atomic_set(&clone->a_refcount, 1); - } } return clone; } diff --git a/fs/proc/array.c b/fs/proc/array.c index c0e554971df..25e917fb473 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -162,7 +162,7 @@ static inline char * task_state(struct task_struct *p, char *buffer) int g; struct fdtable *fdt = NULL; - read_lock(&tasklist_lock); + rcu_read_lock(); buffer += sprintf(buffer, "State:\t%s\n" "SleepAVG:\t%lu%%\n" @@ -174,14 +174,13 @@ static inline char * task_state(struct task_struct *p, char *buffer) "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), (p->sleep_avg/1024)*100/(1020000000/1024), - p->tgid, - p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0, - pid_alive(p) && p->ptrace ? p->parent->pid : 0, + p->tgid, p->pid, + pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, + pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, p->uid, p->euid, p->suid, p->fsuid, p->gid, p->egid, p->sgid, p->fsgid); - read_unlock(&tasklist_lock); + task_lock(p); - rcu_read_lock(); if (p->files) fdt = files_fdtable(p->files); buffer += sprintf(buffer, @@ -244,6 +243,7 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, static inline char * task_sig(struct task_struct *p, char *buffer) { + unsigned long flags; sigset_t pending, shpending, blocked, ignored, caught; int num_threads = 0; unsigned long qsize = 0; @@ -255,10 +255,8 @@ static inline char * task_sig(struct task_struct *p, char *buffer) sigemptyset(&ignored); sigemptyset(&caught); - /* Gather all the data with the appropriate locks held */ - read_lock(&tasklist_lock); - if (p->sighand) { - spin_lock_irq(&p->sighand->siglock); + rcu_read_lock(); + if (lock_task_sighand(p, &flags)) { pending = p->pending.signal; shpending = p->signal->shared_pending.signal; blocked = p->blocked; @@ -266,9 +264,9 @@ static inline char * task_sig(struct task_struct *p, char *buffer) num_threads = atomic_read(&p->signal->count); qsize = atomic_read(&p->user->sigpending); qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; - spin_unlock_irq(&p->sighand->siglock); + unlock_task_sighand(p, &flags); } - read_unlock(&tasklist_lock); + rcu_read_unlock(); buffer += sprintf(buffer, "Threads:\t%d\n", num_threads); buffer += sprintf(buffer, "SigQ:\t%lu/%lu\n", qsize, qlim); @@ -322,7 +320,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) sigset_t sigign, sigcatch; char state; int res; - pid_t ppid, pgid = -1, sid = -1; + pid_t ppid = 0, pgid = -1, sid = -1; int num_threads = 0; struct mm_struct *mm; unsigned long long start_time; @@ -330,8 +328,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) unsigned long min_flt = 0, maj_flt = 0; cputime_t cutime, cstime, utime, stime; unsigned long rsslim = 0; - struct task_struct *t; char tcomm[sizeof(task->comm)]; + unsigned long flags; state = *get_task_state(task); vsize = eip = esp = 0; @@ -349,15 +347,33 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) cutime = cstime = utime = stime = cputime_zero; mutex_lock(&tty_mutex); - read_lock(&tasklist_lock); - if (task->sighand) { - spin_lock_irq(&task->sighand->siglock); - num_threads = atomic_read(&task->signal->count); + rcu_read_lock(); + if (lock_task_sighand(task, &flags)) { + struct signal_struct *sig = task->signal; + struct tty_struct *tty = sig->tty; + + if (tty) { + /* + * sig->tty is not stable, but tty_mutex + * protects us from release_dev(tty) + */ + barrier(); + tty_pgrp = tty->pgrp; + tty_nr = new_encode_dev(tty_devnum(tty)); + } + + num_threads = atomic_read(&sig->count); collect_sigign_sigcatch(task, &sigign, &sigcatch); + cmin_flt = sig->cmin_flt; + cmaj_flt = sig->cmaj_flt; + cutime = sig->cutime; + cstime = sig->cstime; + rsslim = sig->rlim[RLIMIT_RSS].rlim_cur; + /* add up live thread stats at the group level */ if (whole) { - t = task; + struct task_struct *t = task; do { min_flt += t->min_flt; maj_flt += t->maj_flt; @@ -365,31 +381,20 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) stime = cputime_add(stime, t->stime); t = next_thread(t); } while (t != task); - } - spin_unlock_irq(&task->sighand->siglock); - } - if (task->signal) { - if (task->signal->tty) { - tty_pgrp = task->signal->tty->pgrp; - tty_nr = new_encode_dev(tty_devnum(task->signal->tty)); + min_flt += sig->min_flt; + maj_flt += sig->maj_flt; + utime = cputime_add(utime, sig->utime); + stime = cputime_add(stime, sig->stime); } + + sid = sig->session; pgid = process_group(task); - sid = task->signal->session; - cmin_flt = task->signal->cmin_flt; - cmaj_flt = task->signal->cmaj_flt; - cutime = task->signal->cutime; - cstime = task->signal->cstime; - rsslim = task->signal->rlim[RLIMIT_RSS].rlim_cur; - if (whole) { - min_flt += task->signal->min_flt; - maj_flt += task->signal->maj_flt; - utime = cputime_add(utime, task->signal->utime); - stime = cputime_add(stime, task->signal->stime); - } + ppid = rcu_dereference(task->real_parent)->tgid; + + unlock_task_sighand(task, &flags); } - ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0; - read_unlock(&tasklist_lock); + rcu_read_unlock(); mutex_unlock(&tty_mutex); if (!whole || num_threads<2) diff --git a/fs/proc/base.c b/fs/proc/base.c index 89c20d9d50b..82da55b5cff 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -71,6 +71,7 @@ #include <linux/cpuset.h> #include <linux/audit.h> #include <linux/poll.h> +#include <linux/nsproxy.h> #include "internal.h" /* NOTE: @@ -83,262 +84,44 @@ * in /proc for a task before it execs a suid executable. */ -/* - * For hysterical raisins we keep the same inumbers as in the old procfs. - * Feel free to change the macro below - just keep the range distinct from - * inumbers of the rest of procfs (currently those are in 0x0000--0xffff). - * As soon as we'll get a separate superblock we will be able to forget - * about magical ranges too. - */ - -#define fake_ino(pid,ino) (((pid)<<16)|(ino)) - -enum pid_directory_inos { - PROC_TGID_INO = 2, - PROC_TGID_TASK, - PROC_TGID_STATUS, - PROC_TGID_MEM, -#ifdef CONFIG_SECCOMP - PROC_TGID_SECCOMP, -#endif - PROC_TGID_CWD, - PROC_TGID_ROOT, - PROC_TGID_EXE, - PROC_TGID_FD, - PROC_TGID_ENVIRON, - PROC_TGID_AUXV, - PROC_TGID_CMDLINE, - PROC_TGID_STAT, - PROC_TGID_STATM, - PROC_TGID_MAPS, - PROC_TGID_NUMA_MAPS, - PROC_TGID_MOUNTS, - PROC_TGID_MOUNTSTATS, - PROC_TGID_WCHAN, -#ifdef CONFIG_MMU - PROC_TGID_SMAPS, -#endif -#ifdef CONFIG_SCHEDSTATS - PROC_TGID_SCHEDSTAT, -#endif -#ifdef CONFIG_CPUSETS - PROC_TGID_CPUSET, -#endif -#ifdef CONFIG_SECURITY - PROC_TGID_ATTR, - PROC_TGID_ATTR_CURRENT, - PROC_TGID_ATTR_PREV, - PROC_TGID_ATTR_EXEC, - PROC_TGID_ATTR_FSCREATE, - PROC_TGID_ATTR_KEYCREATE, - PROC_TGID_ATTR_SOCKCREATE, -#endif -#ifdef CONFIG_AUDITSYSCALL - PROC_TGID_LOGINUID, -#endif - PROC_TGID_OOM_SCORE, - PROC_TGID_OOM_ADJUST, - PROC_TID_INO, - PROC_TID_STATUS, - PROC_TID_MEM, -#ifdef CONFIG_SECCOMP - PROC_TID_SECCOMP, -#endif - PROC_TID_CWD, - PROC_TID_ROOT, - PROC_TID_EXE, - PROC_TID_FD, - PROC_TID_ENVIRON, - PROC_TID_AUXV, - PROC_TID_CMDLINE, - PROC_TID_STAT, - PROC_TID_STATM, - PROC_TID_MAPS, - PROC_TID_NUMA_MAPS, - PROC_TID_MOUNTS, - PROC_TID_MOUNTSTATS, - PROC_TID_WCHAN, -#ifdef CONFIG_MMU - PROC_TID_SMAPS, -#endif -#ifdef CONFIG_SCHEDSTATS - PROC_TID_SCHEDSTAT, -#endif -#ifdef CONFIG_CPUSETS - PROC_TID_CPUSET, -#endif -#ifdef CONFIG_SECURITY - PROC_TID_ATTR, - PROC_TID_ATTR_CURRENT, - PROC_TID_ATTR_PREV, - PROC_TID_ATTR_EXEC, - PROC_TID_ATTR_FSCREATE, - PROC_TID_ATTR_KEYCREATE, - PROC_TID_ATTR_SOCKCREATE, -#endif -#ifdef CONFIG_AUDITSYSCALL - PROC_TID_LOGINUID, -#endif - PROC_TID_OOM_SCORE, - PROC_TID_OOM_ADJUST, - - /* Add new entries before this */ - PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */ -}; /* Worst case buffer size needed for holding an integer. */ #define PROC_NUMBUF 10 struct pid_entry { - int type; int len; char *name; mode_t mode; + struct inode_operations *iop; + struct file_operations *fop; + union proc_op op; }; -#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)} - -static struct pid_entry tgid_base_stuff[] = { - E(PROC_TGID_TASK, "task", S_IFDIR|S_IRUGO|S_IXUGO), - E(PROC_TGID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR), - E(PROC_TGID_ENVIRON, "environ", S_IFREG|S_IRUSR), - E(PROC_TGID_AUXV, "auxv", S_IFREG|S_IRUSR), - E(PROC_TGID_STATUS, "status", S_IFREG|S_IRUGO), - E(PROC_TGID_CMDLINE, "cmdline", S_IFREG|S_IRUGO), - E(PROC_TGID_STAT, "stat", S_IFREG|S_IRUGO), - E(PROC_TGID_STATM, "statm", S_IFREG|S_IRUGO), - E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUGO), -#ifdef CONFIG_NUMA - E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO), -#endif - E(PROC_TGID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR), -#ifdef CONFIG_SECCOMP - E(PROC_TGID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR), -#endif - E(PROC_TGID_CWD, "cwd", S_IFLNK|S_IRWXUGO), - E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), - E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), - E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), - E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR), -#ifdef CONFIG_MMU - E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO), -#endif -#ifdef CONFIG_SECURITY - E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), -#endif -#ifdef CONFIG_KALLSYMS - E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO), -#endif -#ifdef CONFIG_SCHEDSTATS - E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO), -#endif -#ifdef CONFIG_CPUSETS - E(PROC_TGID_CPUSET, "cpuset", S_IFREG|S_IRUGO), -#endif - E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO), - E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR), -#ifdef CONFIG_AUDITSYSCALL - E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO), -#endif - {0,0,NULL,0} -}; -static struct pid_entry tid_base_stuff[] = { - E(PROC_TID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR), - E(PROC_TID_ENVIRON, "environ", S_IFREG|S_IRUSR), - E(PROC_TID_AUXV, "auxv", S_IFREG|S_IRUSR), - E(PROC_TID_STATUS, "status", S_IFREG|S_IRUGO), - E(PROC_TID_CMDLINE, "cmdline", S_IFREG|S_IRUGO), - E(PROC_TID_STAT, "stat", S_IFREG|S_IRUGO), - E(PROC_TID_STATM, "statm", S_IFREG|S_IRUGO), - E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUGO), -#ifdef CONFIG_NUMA - E(PROC_TID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO), -#endif - E(PROC_TID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR), -#ifdef CONFIG_SECCOMP - E(PROC_TID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR), -#endif - E(PROC_TID_CWD, "cwd", S_IFLNK|S_IRWXUGO), - E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), - E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), - E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), -#ifdef CONFIG_MMU - E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO), -#endif -#ifdef CONFIG_SECURITY - E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), -#endif -#ifdef CONFIG_KALLSYMS - E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO), -#endif -#ifdef CONFIG_SCHEDSTATS - E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO), -#endif -#ifdef CONFIG_CPUSETS - E(PROC_TID_CPUSET, "cpuset", S_IFREG|S_IRUGO), -#endif - E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO), - E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR), -#ifdef CONFIG_AUDITSYSCALL - E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO), -#endif - {0,0,NULL,0} -}; - -#ifdef CONFIG_SECURITY -static struct pid_entry tgid_attr_stuff[] = { - E(PROC_TGID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO), - E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO), - {0,0,NULL,0} -}; -static struct pid_entry tid_attr_stuff[] = { - E(PROC_TID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO), - E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO), - E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO), - {0,0,NULL,0} -}; -#endif - -#undef E - -static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) -{ - struct task_struct *task = get_proc_task(inode); - struct files_struct *files = NULL; - struct file *file; - int fd = proc_fd(inode); - - if (task) { - files = get_files_struct(task); - put_task_struct(task); - } - if (files) { - /* - * We are not taking a ref to the file structure, so we must - * hold ->file_lock. - */ - spin_lock(&files->file_lock); - file = fcheck_files(files, fd); - if (file) { - *mnt = mntget(file->f_vfsmnt); - *dentry = dget(file->f_dentry); - spin_unlock(&files->file_lock); - put_files_struct(files); - return 0; - } - spin_unlock(&files->file_lock); - put_files_struct(files); - } - return -ENOENT; +#define NOD(NAME, MODE, IOP, FOP, OP) { \ + .len = sizeof(NAME) - 1, \ + .name = (NAME), \ + .mode = MODE, \ + .iop = IOP, \ + .fop = FOP, \ + .op = OP, \ } +#define DIR(NAME, MODE, OTYPE) \ + NOD(NAME, (S_IFDIR|(MODE)), \ + &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \ + {} ) +#define LNK(NAME, OTYPE) \ + NOD(NAME, (S_IFLNK|S_IRWXUGO), \ + &proc_pid_link_inode_operations, NULL, \ + { .proc_get_link = &proc_##OTYPE##_link } ) +#define REG(NAME, MODE, OTYPE) \ + NOD(NAME, (S_IFREG|(MODE)), NULL, \ + &proc_##OTYPE##_operations, {}) +#define INF(NAME, MODE, OTYPE) \ + NOD(NAME, (S_IFREG|(MODE)), \ + NULL, &proc_info_file_operations, \ + { .proc_read = &proc_##OTYPE } ) + static struct fs_struct *get_fs_struct(struct task_struct *task) { struct fs_struct *fs; @@ -587,7 +370,7 @@ static int mounts_open(struct inode *inode, struct file *file) if (task) { task_lock(task); - namespace = task->namespace; + namespace = task->nsproxy->namespace; if (namespace) get_namespace(namespace); task_unlock(task); @@ -658,7 +441,7 @@ static int mountstats_open(struct inode *inode, struct file *file) if (task) { task_lock(task); - namespace = task->namespace; + namespace = task->nsproxy->namespace; if (namespace) get_namespace(namespace); task_unlock(task); @@ -1137,143 +920,6 @@ static struct inode_operations proc_pid_link_inode_operations = { .setattr = proc_setattr, }; -static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) -{ - struct dentry *dentry = filp->f_dentry; - struct inode *inode = dentry->d_inode; - struct task_struct *p = get_proc_task(inode); - unsigned int fd, tid, ino; - int retval; - char buf[PROC_NUMBUF]; - struct files_struct * files; - struct fdtable *fdt; - - retval = -ENOENT; - if (!p) - goto out_no_task; - retval = 0; - tid = p->pid; - - fd = filp->f_pos; - switch (fd) { - case 0: - if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) - goto out; - filp->f_pos++; - case 1: - ino = parent_ino(dentry); - if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) - goto out; - filp->f_pos++; - default: - files = get_files_struct(p); - if (!files) - goto out; - rcu_read_lock(); - fdt = files_fdtable(files); - for (fd = filp->f_pos-2; - fd < fdt->max_fds; - fd++, filp->f_pos++) { - unsigned int i,j; - - if (!fcheck_files(files, fd)) - continue; - rcu_read_unlock(); - - j = PROC_NUMBUF; - i = fd; - do { - j--; - buf[j] = '0' + (i % 10); - i /= 10; - } while (i); - - ino = fake_ino(tid, PROC_TID_FD_DIR + fd); - if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) { - rcu_read_lock(); - break; - } - rcu_read_lock(); - } - rcu_read_unlock(); - put_files_struct(files); - } -out: - put_task_struct(p); -out_no_task: - return retval; -} - -static int proc_pident_readdir(struct file *filp, - void *dirent, filldir_t filldir, - struct pid_entry *ents, unsigned int nents) -{ - int i; - int pid; - struct dentry *dentry = filp->f_dentry; - struct inode *inode = dentry->d_inode; - struct task_struct *task = get_proc_task(inode); - struct pid_entry *p; - ino_t ino; - int ret; - - ret = -ENOENT; - if (!task) - goto out; - - ret = 0; - pid = task->pid; - put_task_struct(task); - i = filp->f_pos; - switch (i) { - case 0: - ino = inode->i_ino; - if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) - goto out; - i++; - filp->f_pos++; - /* fall through */ - case 1: - ino = parent_ino(dentry); - if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) - goto out; - i++; - filp->f_pos++; - /* fall through */ - default: - i -= 2; - if (i >= nents) { - ret = 1; - goto out; - } - p = ents + i; - while (p->name) { - if (filldir(dirent, p->name, p->len, filp->f_pos, - fake_ino(pid, p->type), p->mode >> 12) < 0) - goto out; - filp->f_pos++; - p++; - } - } - - ret = 1; -out: - return ret; -} - -static int proc_tgid_base_readdir(struct file * filp, - void * dirent, filldir_t filldir) -{ - return proc_pident_readdir(filp,dirent,filldir, - tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff)); -} - -static int proc_tid_base_readdir(struct file * filp, - void * dirent, filldir_t filldir) -{ - return proc_pident_readdir(filp,dirent,filldir, - tid_base_stuff,ARRAY_SIZE(tid_base_stuff)); -} /* building an inode */ @@ -1293,13 +939,13 @@ static int task_dumpable(struct task_struct *task) } -static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino) +static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task) { struct inode * inode; struct proc_inode *ei; /* We need a new inode */ - + inode = new_inode(sb); if (!inode) goto out; @@ -1307,13 +953,12 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st /* Common stuff */ ei = PROC_I(inode); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_ino = fake_ino(task->pid, ino); inode->i_op = &proc_def_inode_operations; /* * grab the reference to task. */ - ei->pid = get_pid(task->pids[PIDTYPE_PID].pid); + ei->pid = get_task_pid(task, PIDTYPE_PID); if (!ei->pid) goto out_unlock; @@ -1333,6 +978,27 @@ out_unlock: return NULL; } +static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + struct task_struct *task; + generic_fillattr(inode, stat); + + rcu_read_lock(); + stat->uid = 0; + stat->gid = 0; + task = pid_task(proc_pid(inode), PIDTYPE_PID); + if (task) { + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || + task_dumpable(task)) { + stat->uid = task->euid; + stat->gid = task->egid; + } + } + rcu_read_unlock(); + return 0; +} + /* dentry stuff */ /* @@ -1372,25 +1038,130 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) return 0; } -static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +static int pid_delete_dentry(struct dentry * dentry) { - struct inode *inode = dentry->d_inode; - struct task_struct *task; - generic_fillattr(inode, stat); + /* Is the task we represent dead? + * If so, then don't put the dentry on the lru list, + * kill it immediately. + */ + return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; +} + +static struct dentry_operations pid_dentry_operations = +{ + .d_revalidate = pid_revalidate, + .d_delete = pid_delete_dentry, +}; + +/* Lookups */ + +typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *); + +/* + * Fill a directory entry. + * + * If possible create the dcache entry and derive our inode number and + * file type from dcache entry. + * + * Since all of the proc inode numbers are dynamically generated, the inode + * numbers do not exist until the inode is cache. This means creating the + * the dcache entry in readdir is necessary to keep the inode numbers + * reported by readdir in sync with the inode numbers reported + * by stat. + */ +static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + char *name, int len, + instantiate_t instantiate, struct task_struct *task, void *ptr) +{ + struct dentry *child, *dir = filp->f_dentry; + struct inode *inode; + struct qstr qname; + ino_t ino = 0; + unsigned type = DT_UNKNOWN; + + qname.name = name; + qname.len = len; + qname.hash = full_name_hash(name, len); + + child = d_lookup(dir, &qname); + if (!child) { + struct dentry *new; + new = d_alloc(dir, &qname); + if (new) { + child = instantiate(dir->d_inode, new, task, ptr); + if (child) + dput(new); + else + child = new; + } + } + if (!child || IS_ERR(child) || !child->d_inode) + goto end_instantiate; + inode = child->d_inode; + if (inode) { + ino = inode->i_ino; + type = inode->i_mode >> 12; + } + dput(child); +end_instantiate: + if (!ino) + ino = find_inode_number(dir, &qname); + if (!ino) + ino = 1; + return filldir(dirent, name, len, filp->f_pos, ino, type); +} + +static unsigned name_to_int(struct dentry *dentry) +{ + const char *name = dentry->d_name.name; + int len = dentry->d_name.len; + unsigned n = 0; + + if (len > 1 && *name == '0') + goto out; + while (len-- > 0) { + unsigned c = *name++ - '0'; + if (c > 9) + goto out; + if (n >= (~0U-9)/10) + goto out; + n *= 10; + n += c; + } + return n; +out: + return ~0U; +} + +static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) +{ + struct task_struct *task = get_proc_task(inode); + struct files_struct *files = NULL; + struct file *file; + int fd = proc_fd(inode); - rcu_read_lock(); - stat->uid = 0; - stat->gid = 0; - task = pid_task(proc_pid(inode), PIDTYPE_PID); if (task) { - if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || - task_dumpable(task)) { - stat->uid = task->euid; - stat->gid = task->egid; + files = get_files_struct(task); + put_task_struct(task); + } + if (files) { + /* + * We are not taking a ref to the file structure, so we must + * hold ->file_lock. + */ + spin_lock(&files->file_lock); + file = fcheck_files(files, fd); + if (file) { + *mnt = mntget(file->f_vfsmnt); + *dentry = dget(file->f_dentry); + spin_unlock(&files->file_lock); + put_files_struct(files); + return 0; } + spin_unlock(&files->file_lock); + put_files_struct(files); } - rcu_read_unlock(); - return 0; + return -ENOENT; } static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) @@ -1428,75 +1199,30 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) return 0; } -static int pid_delete_dentry(struct dentry * dentry) -{ - /* Is the task we represent dead? - * If so, then don't put the dentry on the lru list, - * kill it immediately. - */ - return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; -} - static struct dentry_operations tid_fd_dentry_operations = { .d_revalidate = tid_fd_revalidate, .d_delete = pid_delete_dentry, }; -static struct dentry_operations pid_dentry_operations = -{ - .d_revalidate = pid_revalidate, - .d_delete = pid_delete_dentry, -}; - -/* Lookups */ - -static unsigned name_to_int(struct dentry *dentry) -{ - const char *name = dentry->d_name.name; - int len = dentry->d_name.len; - unsigned n = 0; - - if (len > 1 && *name == '0') - goto out; - while (len-- > 0) { - unsigned c = *name++ - '0'; - if (c > 9) - goto out; - if (n >= (~0U-9)/10) - goto out; - n *= 10; - n += c; - } - return n; -out: - return ~0U; -} - -/* SMP-safe */ -static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) +static struct dentry *proc_fd_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) { - struct task_struct *task = get_proc_task(dir); - unsigned fd = name_to_int(dentry); - struct dentry *result = ERR_PTR(-ENOENT); - struct file * file; - struct files_struct * files; - struct inode *inode; - struct proc_inode *ei; - - if (!task) - goto out_no_task; - if (fd == ~0U) - goto out; + unsigned fd = *(unsigned *)ptr; + struct file *file; + struct files_struct *files; + struct inode *inode; + struct proc_inode *ei; + struct dentry *error = ERR_PTR(-ENOENT); - inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd); + inode = proc_pid_make_inode(dir->i_sb, task); if (!inode) goto out; ei = PROC_I(inode); ei->fd = fd; files = get_files_struct(task); if (!files) - goto out_unlock; + goto out_iput; inode->i_mode = S_IFLNK; /* @@ -1506,13 +1232,14 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (!file) - goto out_unlock2; + goto out_unlock; if (file->f_mode & 1) inode->i_mode |= S_IRUSR | S_IXUSR; if (file->f_mode & 2) inode->i_mode |= S_IWUSR | S_IXUSR; spin_unlock(&files->file_lock); put_files_struct(files); + inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; ei->op.proc_get_link = proc_fd_link; @@ -1520,34 +1247,106 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, d_add(dentry, inode); /* Close the race of the process dying before we return the dentry */ if (tid_fd_revalidate(dentry, NULL)) - result = NULL; -out: - put_task_struct(task); -out_no_task: - return result; + error = NULL; -out_unlock2: + out: + return error; +out_unlock: spin_unlock(&files->file_lock); put_files_struct(files); -out_unlock: +out_iput: iput(inode); goto out; } -static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir); -static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd); -static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); +static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) +{ + struct task_struct *task = get_proc_task(dir); + unsigned fd = name_to_int(dentry); + struct dentry *result = ERR_PTR(-ENOENT); + + if (!task) + goto out_no_task; + if (fd == ~0U) + goto out; + + result = proc_fd_instantiate(dir, dentry, task, &fd); +out: + put_task_struct(task); +out_no_task: + return result; +} + +static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct task_struct *task, int fd) +{ + char name[PROC_NUMBUF]; + int len = snprintf(name, sizeof(name), "%d", fd); + return proc_fill_cache(filp, dirent, filldir, name, len, + proc_fd_instantiate, task, &fd); +} + +static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) +{ + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; + struct task_struct *p = get_proc_task(inode); + unsigned int fd, tid, ino; + int retval; + struct files_struct * files; + struct fdtable *fdt; + + retval = -ENOENT; + if (!p) + goto out_no_task; + retval = 0; + tid = p->pid; + + fd = filp->f_pos; + switch (fd) { + case 0: + if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) + goto out; + filp->f_pos++; + case 1: + ino = parent_ino(dentry); + if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) + goto out; + filp->f_pos++; + default: + files = get_files_struct(p); + if (!files) + goto out; + rcu_read_lock(); + fdt = files_fdtable(files); + for (fd = filp->f_pos-2; + fd < fdt->max_fds; + fd++, filp->f_pos++) { + + if (!fcheck_files(files, fd)) + continue; + rcu_read_unlock(); + + if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) { + rcu_read_lock(); + break; + } + rcu_read_lock(); + } + rcu_read_unlock(); + put_files_struct(files); + } +out: + put_task_struct(p); +out_no_task: + return retval; +} static struct file_operations proc_fd_operations = { .read = generic_read_dir, .readdir = proc_readfd, }; -static struct file_operations proc_task_operations = { - .read = generic_read_dir, - .readdir = proc_task_readdir, -}; - /* * proc directories can do almost nothing.. */ @@ -1556,11 +1355,137 @@ static struct inode_operations proc_fd_inode_operations = { .setattr = proc_setattr, }; -static struct inode_operations proc_task_inode_operations = { - .lookup = proc_task_lookup, - .getattr = proc_task_getattr, - .setattr = proc_setattr, -}; +static struct dentry *proc_pident_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) +{ + struct pid_entry *p = ptr; + struct inode *inode; + struct proc_inode *ei; + struct dentry *error = ERR_PTR(-EINVAL); + + inode = proc_pid_make_inode(dir->i_sb, task); + if (!inode) + goto out; + + ei = PROC_I(inode); + inode->i_mode = p->mode; + if (S_ISDIR(inode->i_mode)) + inode->i_nlink = 2; /* Use getattr to fix if necessary */ + if (p->iop) + inode->i_op = p->iop; + if (p->fop) + inode->i_fop = p->fop; + ei->op = p->op; + dentry->d_op = &pid_dentry_operations; + d_add(dentry, inode); + /* Close the race of the process dying before we return the dentry */ + if (pid_revalidate(dentry, NULL)) + error = NULL; +out: + return error; +} + +static struct dentry *proc_pident_lookup(struct inode *dir, + struct dentry *dentry, + struct pid_entry *ents, + unsigned int nents) +{ + struct inode *inode; + struct dentry *error; + struct task_struct *task = get_proc_task(dir); + struct pid_entry *p, *last; + + error = ERR_PTR(-ENOENT); + inode = NULL; + + if (!task) + goto out_no_task; + + /* + * Yes, it does not scale. And it should not. Don't add + * new entries into /proc/<tgid>/ without very good reasons. + */ + last = &ents[nents - 1]; + for (p = ents; p <= last; p++) { + if (p->len != dentry->d_name.len) + continue; + if (!memcmp(dentry->d_name.name, p->name, p->len)) + break; + } + if (p > last) + goto out; + + error = proc_pident_instantiate(dir, dentry, task, p); +out: + put_task_struct(task); +out_no_task: + return error; +} + +static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct task_struct *task, struct pid_entry *p) +{ + return proc_fill_cache(filp, dirent, filldir, p->name, p->len, + proc_pident_instantiate, task, p); +} + +static int proc_pident_readdir(struct file *filp, + void *dirent, filldir_t filldir, + struct pid_entry *ents, unsigned int nents) +{ + int i; + int pid; + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; + struct task_struct *task = get_proc_task(inode); + struct pid_entry *p, *last; + ino_t ino; + int ret; + + ret = -ENOENT; + if (!task) + goto out_no_task; + + ret = 0; + pid = task->pid; + i = filp->f_pos; + switch (i) { + case 0: + ino = inode->i_ino; + if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) + goto out; + i++; + filp->f_pos++; + /* fall through */ + case 1: + ino = parent_ino(dentry); + if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) + goto out; + i++; + filp->f_pos++; + /* fall through */ + default: + i -= 2; + if (i >= nents) { + ret = 1; + goto out; + } + p = ents + i; + last = &ents[nents - 1]; + while (p <= last) { + if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0) + goto out; + filp->f_pos++; + p++; + } + } + + ret = 1; +out: + put_task_struct(task); +out_no_task: + return ret; +} #ifdef CONFIG_SECURITY static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, @@ -1581,8 +1506,8 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, if (!(page = __get_free_page(GFP_KERNEL))) goto out; - length = security_getprocattr(task, - (char*)file->f_dentry->d_name.name, + length = security_getprocattr(task, + (char*)file->f_dentry->d_name.name, (void*)page, count); if (length >= 0) length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); @@ -1595,17 +1520,17 @@ out_no_task: static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) -{ +{ struct inode * inode = file->f_dentry->d_inode; - char *page; - ssize_t length; + char *page; + ssize_t length; struct task_struct *task = get_proc_task(inode); length = -ESRCH; if (!task) goto out_no_task; - if (count > PAGE_SIZE) - count = PAGE_SIZE; + if (count > PAGE_SIZE) + count = PAGE_SIZE; /* No partial writes. */ length = -EINVAL; @@ -1613,16 +1538,16 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, goto out; length = -ENOMEM; - page = (char*)__get_free_page(GFP_USER); - if (!page) + page = (char*)__get_free_page(GFP_USER); + if (!page) goto out; - length = -EFAULT; - if (copy_from_user(page, buf, count)) + length = -EFAULT; + if (copy_from_user(page, buf, count)) goto out_free; - length = security_setprocattr(task, - (char*)file->f_dentry->d_name.name, + length = security_setprocattr(task, + (char*)file->f_dentry->d_name.name, (void*)page, count); out_free: free_page((unsigned long) page); @@ -1630,330 +1555,263 @@ out: put_task_struct(task); out_no_task: return length; -} +} static struct file_operations proc_pid_attr_operations = { .read = proc_pid_attr_read, .write = proc_pid_attr_write, }; -static struct file_operations proc_tid_attr_operations; -static struct inode_operations proc_tid_attr_inode_operations; -static struct file_operations proc_tgid_attr_operations; -static struct inode_operations proc_tgid_attr_inode_operations; +static struct pid_entry attr_dir_stuff[] = { + REG("current", S_IRUGO|S_IWUGO, pid_attr), + REG("prev", S_IRUGO, pid_attr), + REG("exec", S_IRUGO|S_IWUGO, pid_attr), + REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), + REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), + REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), +}; + +static int proc_attr_dir_readdir(struct file * filp, + void * dirent, filldir_t filldir) +{ + return proc_pident_readdir(filp,dirent,filldir, + attr_dir_stuff,ARRAY_SIZE(attr_dir_stuff)); +} + +static struct file_operations proc_attr_dir_operations = { + .read = generic_read_dir, + .readdir = proc_attr_dir_readdir, +}; + +static struct dentry *proc_attr_dir_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) +{ + return proc_pident_lookup(dir, dentry, + attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); +} + +static struct inode_operations proc_attr_dir_inode_operations = { + .lookup = proc_attr_dir_lookup, + .getattr = pid_getattr, + .setattr = proc_setattr, +}; + #endif -/* SMP-safe */ -static struct dentry *proc_pident_lookup(struct inode *dir, - struct dentry *dentry, - struct pid_entry *ents) +/* + * /proc/self: + */ +static int proc_self_readlink(struct dentry *dentry, char __user *buffer, + int buflen) +{ + char tmp[PROC_NUMBUF]; + sprintf(tmp, "%d", current->tgid); + return vfs_readlink(dentry,buffer,buflen,tmp); +} + +static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) { + char tmp[PROC_NUMBUF]; + sprintf(tmp, "%d", current->tgid); + return ERR_PTR(vfs_follow_link(nd,tmp)); +} + +static struct inode_operations proc_self_inode_operations = { + .readlink = proc_self_readlink, + .follow_link = proc_self_follow_link, +}; + +/* + * proc base + * + * These are the directory entries in the root directory of /proc + * that properly belong to the /proc filesystem, as they describe + * describe something that is process related. + */ +static struct pid_entry proc_base_stuff[] = { + NOD("self", S_IFLNK|S_IRWXUGO, + &proc_self_inode_operations, NULL, {}), +}; + +/* + * Exceptional case: normally we are not allowed to unhash a busy + * directory. In this case, however, we can do it - no aliasing problems + * due to the way we treat inodes. + */ +static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + struct inode *inode = dentry->d_inode; + struct task_struct *task = get_proc_task(inode); + if (task) { + put_task_struct(task); + return 1; + } + d_drop(dentry); + return 0; +} + +static struct dentry_operations proc_base_dentry_operations = +{ + .d_revalidate = proc_base_revalidate, + .d_delete = pid_delete_dentry, +}; + +static struct dentry *proc_base_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) +{ + struct pid_entry *p = ptr; struct inode *inode; + struct proc_inode *ei; + struct dentry *error = ERR_PTR(-EINVAL); + + /* Allocate the inode */ + error = ERR_PTR(-ENOMEM); + inode = new_inode(dir->i_sb); + if (!inode) + goto out; + + /* Initialize the inode */ + ei = PROC_I(inode); + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + + /* + * grab the reference to the task. + */ + ei->pid = get_task_pid(task, PIDTYPE_PID); + if (!ei->pid) + goto out_iput; + + inode->i_uid = 0; + inode->i_gid = 0; + inode->i_mode = p->mode; + if (S_ISDIR(inode->i_mode)) + inode->i_nlink = 2; + if (S_ISLNK(inode->i_mode)) + inode->i_size = 64; + if (p->iop) + inode->i_op = p->iop; + if (p->fop) + inode->i_fop = p->fop; + ei->op = p->op; + dentry->d_op = &proc_base_dentry_operations; + d_add(dentry, inode); + error = NULL; +out: + return error; +out_iput: + iput(inode); + goto out; +} + +static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) +{ struct dentry *error; struct task_struct *task = get_proc_task(dir); - struct pid_entry *p; - struct proc_inode *ei; + struct pid_entry *p, *last; error = ERR_PTR(-ENOENT); - inode = NULL; if (!task) goto out_no_task; - for (p = ents; p->name; p++) { + /* Lookup the directory entry */ + last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1]; + for (p = proc_base_stuff; p <= last; p++) { if (p->len != dentry->d_name.len) continue; if (!memcmp(dentry->d_name.name, p->name, p->len)) break; } - if (!p->name) + if (p > last) goto out; - error = ERR_PTR(-EINVAL); - inode = proc_pid_make_inode(dir->i_sb, task, p->type); - if (!inode) - goto out; + error = proc_base_instantiate(dir, dentry, task, p); - ei = PROC_I(inode); - inode->i_mode = p->mode; - /* - * Yes, it does not scale. And it should not. Don't add - * new entries into /proc/<tgid>/ without very good reasons. - */ - switch(p->type) { - case PROC_TGID_TASK: - inode->i_nlink = 2; - inode->i_op = &proc_task_inode_operations; - inode->i_fop = &proc_task_operations; - break; - case PROC_TID_FD: - case PROC_TGID_FD: - inode->i_nlink = 2; - inode->i_op = &proc_fd_inode_operations; - inode->i_fop = &proc_fd_operations; - break; - case PROC_TID_EXE: - case PROC_TGID_EXE: - inode->i_op = &proc_pid_link_inode_operations; - ei->op.proc_get_link = proc_exe_link; - break; - case PROC_TID_CWD: - case PROC_TGID_CWD: - inode->i_op = &proc_pid_link_inode_operations; - ei->op.proc_get_link = proc_cwd_link; - break; - case PROC_TID_ROOT: - case PROC_TGID_ROOT: - inode->i_op = &proc_pid_link_inode_operations; - ei->op.proc_get_link = proc_root_link; - break; - case PROC_TID_ENVIRON: - case PROC_TGID_ENVIRON: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_environ; - break; - case PROC_TID_AUXV: - case PROC_TGID_AUXV: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_auxv; - break; - case PROC_TID_STATUS: - case PROC_TGID_STATUS: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_status; - break; - case PROC_TID_STAT: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_tid_stat; - break; - case PROC_TGID_STAT: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_tgid_stat; - break; - case PROC_TID_CMDLINE: - case PROC_TGID_CMDLINE: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_cmdline; - break; - case PROC_TID_STATM: - case PROC_TGID_STATM: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_statm; - break; - case PROC_TID_MAPS: - case PROC_TGID_MAPS: - inode->i_fop = &proc_maps_operations; - break; +out: + put_task_struct(task); +out_no_task: + return error; +} + +static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct task_struct *task, struct pid_entry *p) +{ + return proc_fill_cache(filp, dirent, filldir, p->name, p->len, + proc_base_instantiate, task, p); +} + +/* + * Thread groups + */ +static struct file_operations proc_task_operations; +static struct inode_operations proc_task_inode_operations; + +static struct pid_entry tgid_base_stuff[] = { + DIR("task", S_IRUGO|S_IXUGO, task), + DIR("fd", S_IRUSR|S_IXUSR, fd), + INF("environ", S_IRUSR, pid_environ), + INF("auxv", S_IRUSR, pid_auxv), + INF("status", S_IRUGO, pid_status), + INF("cmdline", S_IRUGO, pid_cmdline), + INF("stat", S_IRUGO, tgid_stat), + INF("statm", S_IRUGO, pid_statm), + REG("maps", S_IRUGO, maps), #ifdef CONFIG_NUMA - case PROC_TID_NUMA_MAPS: - case PROC_TGID_NUMA_MAPS: - inode->i_fop = &proc_numa_maps_operations; - break; + REG("numa_maps", S_IRUGO, numa_maps), #endif - case PROC_TID_MEM: - case PROC_TGID_MEM: - inode->i_fop = &proc_mem_operations; - break; + REG("mem", S_IRUSR|S_IWUSR, mem), #ifdef CONFIG_SECCOMP - case PROC_TID_SECCOMP: - case PROC_TGID_SECCOMP: - inode->i_fop = &proc_seccomp_operations; - break; -#endif /* CONFIG_SECCOMP */ - case PROC_TID_MOUNTS: - case PROC_TGID_MOUNTS: - inode->i_fop = &proc_mounts_operations; - break; + REG("seccomp", S_IRUSR|S_IWUSR, seccomp), +#endif + LNK("cwd", cwd), + LNK("root", root), + LNK("exe", exe), + REG("mounts", S_IRUGO, mounts), + REG("mountstats", S_IRUSR, mountstats), #ifdef CONFIG_MMU - case PROC_TID_SMAPS: - case PROC_TGID_SMAPS: - inode->i_fop = &proc_smaps_operations; - break; + REG("smaps", S_IRUGO, smaps), #endif - case PROC_TID_MOUNTSTATS: - case PROC_TGID_MOUNTSTATS: - inode->i_fop = &proc_mountstats_operations; - break; #ifdef CONFIG_SECURITY - case PROC_TID_ATTR: - inode->i_nlink = 2; - inode->i_op = &proc_tid_attr_inode_operations; - inode->i_fop = &proc_tid_attr_operations; - break; - case PROC_TGID_ATTR: - inode->i_nlink = 2; - inode->i_op = &proc_tgid_attr_inode_operations; - inode->i_fop = &proc_tgid_attr_operations; - break; - case PROC_TID_ATTR_CURRENT: - case PROC_TGID_ATTR_CURRENT: - case PROC_TID_ATTR_PREV: - case PROC_TGID_ATTR_PREV: - case PROC_TID_ATTR_EXEC: - case PROC_TGID_ATTR_EXEC: - case PROC_TID_ATTR_FSCREATE: - case PROC_TGID_ATTR_FSCREATE: - case PROC_TID_ATTR_KEYCREATE: - case PROC_TGID_ATTR_KEYCREATE: - case PROC_TID_ATTR_SOCKCREATE: - case PROC_TGID_ATTR_SOCKCREATE: - inode->i_fop = &proc_pid_attr_operations; - break; + DIR("attr", S_IRUGO|S_IXUGO, attr_dir), #endif #ifdef CONFIG_KALLSYMS - case PROC_TID_WCHAN: - case PROC_TGID_WCHAN: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_wchan; - break; + INF("wchan", S_IRUGO, pid_wchan), #endif #ifdef CONFIG_SCHEDSTATS - case PROC_TID_SCHEDSTAT: - case PROC_TGID_SCHEDSTAT: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_pid_schedstat; - break; + INF("schedstat", S_IRUGO, pid_schedstat), #endif #ifdef CONFIG_CPUSETS - case PROC_TID_CPUSET: - case PROC_TGID_CPUSET: - inode->i_fop = &proc_cpuset_operations; - break; + REG("cpuset", S_IRUGO, cpuset), #endif - case PROC_TID_OOM_SCORE: - case PROC_TGID_OOM_SCORE: - inode->i_fop = &proc_info_file_operations; - ei->op.proc_read = proc_oom_score; - break; - case PROC_TID_OOM_ADJUST: - case PROC_TGID_OOM_ADJUST: - inode->i_fop = &proc_oom_adjust_operations; - break; + INF("oom_score", S_IRUGO, oom_score), + REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), #ifdef CONFIG_AUDITSYSCALL - case PROC_TID_LOGINUID: - case PROC_TGID_LOGINUID: - inode->i_fop = &proc_loginuid_operations; - break; + REG("loginuid", S_IWUSR|S_IRUGO, loginuid), #endif - default: - printk("procfs: impossible type (%d)",p->type); - iput(inode); - error = ERR_PTR(-EINVAL); - goto out; - } - dentry->d_op = &pid_dentry_operations; - d_add(dentry, inode); - /* Close the race of the process dying before we return the dentry */ - if (pid_revalidate(dentry, NULL)) - error = NULL; -out: - put_task_struct(task); -out_no_task: - return error; -} - -static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ - return proc_pident_lookup(dir, dentry, tgid_base_stuff); -} - -static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ - return proc_pident_lookup(dir, dentry, tid_base_stuff); -} - -static struct file_operations proc_tgid_base_operations = { - .read = generic_read_dir, - .readdir = proc_tgid_base_readdir, }; -static struct file_operations proc_tid_base_operations = { - .read = generic_read_dir, - .readdir = proc_tid_base_readdir, -}; - -static struct inode_operations proc_tgid_base_inode_operations = { - .lookup = proc_tgid_base_lookup, - .getattr = pid_getattr, - .setattr = proc_setattr, -}; - -static struct inode_operations proc_tid_base_inode_operations = { - .lookup = proc_tid_base_lookup, - .getattr = pid_getattr, - .setattr = proc_setattr, -}; - -#ifdef CONFIG_SECURITY -static int proc_tgid_attr_readdir(struct file * filp, - void * dirent, filldir_t filldir) -{ - return proc_pident_readdir(filp,dirent,filldir, - tgid_attr_stuff,ARRAY_SIZE(tgid_attr_stuff)); -} - -static int proc_tid_attr_readdir(struct file * filp, +static int proc_tgid_base_readdir(struct file * filp, void * dirent, filldir_t filldir) { return proc_pident_readdir(filp,dirent,filldir, - tid_attr_stuff,ARRAY_SIZE(tid_attr_stuff)); + tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff)); } -static struct file_operations proc_tgid_attr_operations = { - .read = generic_read_dir, - .readdir = proc_tgid_attr_readdir, -}; - -static struct file_operations proc_tid_attr_operations = { +static struct file_operations proc_tgid_base_operations = { .read = generic_read_dir, - .readdir = proc_tid_attr_readdir, + .readdir = proc_tgid_base_readdir, }; -static struct dentry *proc_tgid_attr_lookup(struct inode *dir, - struct dentry *dentry, struct nameidata *nd) -{ - return proc_pident_lookup(dir, dentry, tgid_attr_stuff); -} - -static struct dentry *proc_tid_attr_lookup(struct inode *dir, - struct dentry *dentry, struct nameidata *nd) -{ - return proc_pident_lookup(dir, dentry, tid_attr_stuff); +static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ + return proc_pident_lookup(dir, dentry, + tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); } -static struct inode_operations proc_tgid_attr_inode_operations = { - .lookup = proc_tgid_attr_lookup, - .getattr = pid_getattr, - .setattr = proc_setattr, -}; - -static struct inode_operations proc_tid_attr_inode_operations = { - .lookup = proc_tid_attr_lookup, +static struct inode_operations proc_tgid_base_inode_operations = { + .lookup = proc_tgid_base_lookup, .getattr = pid_getattr, .setattr = proc_setattr, }; -#endif - -/* - * /proc/self: - */ -static int proc_self_readlink(struct dentry *dentry, char __user *buffer, - int buflen) -{ - char tmp[PROC_NUMBUF]; - sprintf(tmp, "%d", current->tgid); - return vfs_readlink(dentry,buffer,buflen,tmp); -} - -static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - char tmp[PROC_NUMBUF]; - sprintf(tmp, "%d", current->tgid); - return ERR_PTR(vfs_follow_link(nd,tmp)); -} - -static struct inode_operations proc_self_inode_operations = { - .readlink = proc_self_readlink, - .follow_link = proc_self_follow_link, -}; /** * proc_flush_task - Remove dcache entries for @task from the /proc dcache. @@ -2022,54 +1880,23 @@ out: return; } -/* SMP-safe */ -struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) +struct dentry *proc_pid_instantiate(struct inode *dir, + struct dentry * dentry, struct task_struct *task, void *ptr) { - struct dentry *result = ERR_PTR(-ENOENT); - struct task_struct *task; + struct dentry *error = ERR_PTR(-ENOENT); struct inode *inode; - struct proc_inode *ei; - unsigned tgid; - - if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) { - inode = new_inode(dir->i_sb); - if (!inode) - return ERR_PTR(-ENOMEM); - ei = PROC_I(inode); - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_ino = fake_ino(0, PROC_TGID_INO); - ei->pde = NULL; - inode->i_mode = S_IFLNK|S_IRWXUGO; - inode->i_uid = inode->i_gid = 0; - inode->i_size = 64; - inode->i_op = &proc_self_inode_operations; - d_add(dentry, inode); - return NULL; - } - tgid = name_to_int(dentry); - if (tgid == ~0U) - goto out; - rcu_read_lock(); - task = find_task_by_pid(tgid); - if (task) - get_task_struct(task); - rcu_read_unlock(); - if (!task) - goto out; - - inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); + inode = proc_pid_make_inode(dir->i_sb, task); if (!inode) - goto out_put_task; + goto out; inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; inode->i_op = &proc_tgid_base_inode_operations; inode->i_fop = &proc_tgid_base_operations; inode->i_flags|=S_IMMUTABLE; -#ifdef CONFIG_SECURITY - inode->i_nlink = 5; -#else inode->i_nlink = 4; +#ifdef CONFIG_SECURITY + inode->i_nlink += 1; #endif dentry->d_op = &pid_dentry_operations; @@ -2077,179 +1904,251 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct d_add(dentry, inode); /* Close the race of the process dying before we return the dentry */ if (pid_revalidate(dentry, NULL)) - result = NULL; - -out_put_task: - put_task_struct(task); + error = NULL; out: - return result; + return error; } -/* SMP-safe */ -static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) +struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) { struct dentry *result = ERR_PTR(-ENOENT); struct task_struct *task; - struct task_struct *leader = get_proc_task(dir); - struct inode *inode; - unsigned tid; + unsigned tgid; - if (!leader) - goto out_no_task; + result = proc_base_lookup(dir, dentry); + if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) + goto out; - tid = name_to_int(dentry); - if (tid == ~0U) + tgid = name_to_int(dentry); + if (tgid == ~0U) goto out; rcu_read_lock(); - task = find_task_by_pid(tid); + task = find_task_by_pid(tgid); if (task) get_task_struct(task); rcu_read_unlock(); if (!task) goto out; - if (leader->tgid != task->tgid) - goto out_drop_task; - - inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); - - - if (!inode) - goto out_drop_task; - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; - inode->i_op = &proc_tid_base_inode_operations; - inode->i_fop = &proc_tid_base_operations; - inode->i_flags|=S_IMMUTABLE; -#ifdef CONFIG_SECURITY - inode->i_nlink = 4; -#else - inode->i_nlink = 3; -#endif - - dentry->d_op = &pid_dentry_operations; - - d_add(dentry, inode); - /* Close the race of the process dying before we return the dentry */ - if (pid_revalidate(dentry, NULL)) - result = NULL; -out_drop_task: + result = proc_pid_instantiate(dir, dentry, task, NULL); put_task_struct(task); out: - put_task_struct(leader); -out_no_task: return result; } /* - * Find the first tgid to return to user space. - * - * Usually this is just whatever follows &init_task, but if the users - * buffer was too small to hold the full list or there was a seek into - * the middle of the directory we have more work to do. - * - * In the case of a short read we start with find_task_by_pid. + * Find the first task with tgid >= tgid * - * In the case of a seek we start with &init_task and walk nr - * threads past it. */ -static struct task_struct *first_tgid(int tgid, unsigned int nr) +static struct task_struct *next_tgid(unsigned int tgid) { - struct task_struct *pos; - rcu_read_lock(); - if (tgid && nr) { - pos = find_task_by_pid(tgid); - if (pos && thread_group_leader(pos)) - goto found; - } - /* If nr exceeds the number of processes get out quickly */ - pos = NULL; - if (nr && nr >= nr_processes()) - goto done; + struct task_struct *task; + struct pid *pid; - /* If we haven't found our starting place yet start with - * the init_task and walk nr tasks forward. - */ - for (pos = next_task(&init_task); nr > 0; --nr) { - pos = next_task(pos); - if (pos == &init_task) { - pos = NULL; - goto done; - } + rcu_read_lock(); +retry: + task = NULL; + pid = find_ge_pid(tgid); + if (pid) { + tgid = pid->nr + 1; + task = pid_task(pid, PIDTYPE_PID); + /* What we to know is if the pid we have find is the + * pid of a thread_group_leader. Testing for task + * being a thread_group_leader is the obvious thing + * todo but there is a window when it fails, due to + * the pid transfer logic in de_thread. + * + * So we perform the straight forward test of seeing + * if the pid we have found is the pid of a thread + * group leader, and don't worry if the task we have + * found doesn't happen to be a thread group leader. + * As we don't care in the case of readdir. + */ + if (!task || !has_group_leader_pid(task)) + goto retry; + get_task_struct(task); } -found: - get_task_struct(pos); -done: rcu_read_unlock(); - return pos; + return task; } -/* - * Find the next task in the task list. - * Return NULL if we loop or there is any error. - * - * The reference to the input task_struct is released. - */ -static struct task_struct *next_tgid(struct task_struct *start) +#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) + +static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct task_struct *task, int tgid) { - struct task_struct *pos; - rcu_read_lock(); - pos = start; - if (pid_alive(start)) - pos = next_task(start); - if (pid_alive(pos) && (pos != &init_task)) { - get_task_struct(pos); - goto done; - } - pos = NULL; -done: - rcu_read_unlock(); - put_task_struct(start); - return pos; + char name[PROC_NUMBUF]; + int len = snprintf(name, sizeof(name), "%d", tgid); + return proc_fill_cache(filp, dirent, filldir, name, len, + proc_pid_instantiate, task, NULL); } /* for the /proc/ directory itself, after non-process stuff has been done */ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) { - char buf[PROC_NUMBUF]; unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; + struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode); struct task_struct *task; int tgid; - if (!nr) { - ino_t ino = fake_ino(0,PROC_TGID_INO); - if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0) - return 0; - filp->f_pos++; - nr++; + if (!reaper) + goto out_no_task; + + for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { + struct pid_entry *p = &proc_base_stuff[nr]; + if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) + goto out; } - nr -= 1; - /* f_version caches the tgid value that the last readdir call couldn't - * return. lseek aka telldir automagically resets f_version to 0. - */ - tgid = filp->f_version; - filp->f_version = 0; - for (task = first_tgid(tgid, nr); + tgid = filp->f_pos - TGID_OFFSET; + for (task = next_tgid(tgid); task; - task = next_tgid(task), filp->f_pos++) { - int len; - ino_t ino; + put_task_struct(task), task = next_tgid(tgid + 1)) { tgid = task->pid; - len = snprintf(buf, sizeof(buf), "%d", tgid); - ino = fake_ino(tgid, PROC_TGID_INO); - if (filldir(dirent, buf, len, filp->f_pos, ino, DT_DIR) < 0) { - /* returning this tgid failed, save it as the first - * pid for the next readir call */ - filp->f_version = tgid; + filp->f_pos = tgid + TGID_OFFSET; + if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { put_task_struct(task); - break; + goto out; } } + filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET; +out: + put_task_struct(reaper); +out_no_task: return 0; } /* + * Tasks + */ +static struct pid_entry tid_base_stuff[] = { + DIR("fd", S_IRUSR|S_IXUSR, fd), + INF("environ", S_IRUSR, pid_environ), + INF("auxv", S_IRUSR, pid_auxv), + INF("status", S_IRUGO, pid_status), + INF("cmdline", S_IRUGO, pid_cmdline), + INF("stat", S_IRUGO, tid_stat), + INF("statm", S_IRUGO, pid_statm), + REG("maps", S_IRUGO, maps), +#ifdef CONFIG_NUMA + REG("numa_maps", S_IRUGO, numa_maps), +#endif + REG("mem", S_IRUSR|S_IWUSR, mem), +#ifdef CONFIG_SECCOMP + REG("seccomp", S_IRUSR|S_IWUSR, seccomp), +#endif + LNK("cwd", cwd), + LNK("root", root), + LNK("exe", exe), + REG("mounts", S_IRUGO, mounts), +#ifdef CONFIG_MMU + REG("smaps", S_IRUGO, smaps), +#endif +#ifdef CONFIG_SECURITY + DIR("attr", S_IRUGO|S_IXUGO, attr_dir), +#endif +#ifdef CONFIG_KALLSYMS + INF("wchan", S_IRUGO, pid_wchan), +#endif +#ifdef CONFIG_SCHEDSTATS + INF("schedstat", S_IRUGO, pid_schedstat), +#endif +#ifdef CONFIG_CPUSETS + REG("cpuset", S_IRUGO, cpuset), +#endif + INF("oom_score", S_IRUGO, oom_score), + REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), +#ifdef CONFIG_AUDITSYSCALL + REG("loginuid", S_IWUSR|S_IRUGO, loginuid), +#endif +}; + +static int proc_tid_base_readdir(struct file * filp, + void * dirent, filldir_t filldir) +{ + return proc_pident_readdir(filp,dirent,filldir, + tid_base_stuff,ARRAY_SIZE(tid_base_stuff)); +} + +static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ + return proc_pident_lookup(dir, dentry, + tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); +} + +static struct file_operations proc_tid_base_operations = { + .read = generic_read_dir, + .readdir = proc_tid_base_readdir, +}; + +static struct inode_operations proc_tid_base_inode_operations = { + .lookup = proc_tid_base_lookup, + .getattr = pid_getattr, + .setattr = proc_setattr, +}; + +static struct dentry *proc_task_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) +{ + struct dentry *error = ERR_PTR(-ENOENT); + struct inode *inode; + inode = proc_pid_make_inode(dir->i_sb, task); + + if (!inode) + goto out; + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; + inode->i_op = &proc_tid_base_inode_operations; + inode->i_fop = &proc_tid_base_operations; + inode->i_flags|=S_IMMUTABLE; + inode->i_nlink = 3; +#ifdef CONFIG_SECURITY + inode->i_nlink += 1; +#endif + + dentry->d_op = &pid_dentry_operations; + + d_add(dentry, inode); + /* Close the race of the process dying before we return the dentry */ + if (pid_revalidate(dentry, NULL)) + error = NULL; +out: + return error; +} + +static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) +{ + struct dentry *result = ERR_PTR(-ENOENT); + struct task_struct *task; + struct task_struct *leader = get_proc_task(dir); + unsigned tid; + + if (!leader) + goto out_no_task; + + tid = name_to_int(dentry); + if (tid == ~0U) + goto out; + + rcu_read_lock(); + task = find_task_by_pid(tid); + if (task) + get_task_struct(task); + rcu_read_unlock(); + if (!task) + goto out; + if (leader->tgid != task->tgid) + goto out_drop_task; + + result = proc_task_instantiate(dir, dentry, task, NULL); +out_drop_task: + put_task_struct(task); +out: + put_task_struct(leader); +out_no_task: + return result; +} + +/* * Find the first tid of a thread group to return to user space. * * Usually this is just the thread group leader, but if the users @@ -2318,10 +2217,18 @@ static struct task_struct *next_tid(struct task_struct *start) return pos; } +static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct task_struct *task, int tid) +{ + char name[PROC_NUMBUF]; + int len = snprintf(name, sizeof(name), "%d", tid); + return proc_fill_cache(filp, dirent, filldir, name, len, + proc_task_instantiate, task, NULL); +} + /* for the /proc/TGID/task/ directories */ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir) { - char buf[PROC_NUMBUF]; struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; struct task_struct *leader = get_proc_task(inode); @@ -2358,11 +2265,8 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi for (task = first_tid(leader, tid, pos - 2); task; task = next_tid(task), pos++) { - int len; tid = task->pid; - len = snprintf(buf, sizeof(buf), "%d", tid); - ino = fake_ino(tid, PROC_TID_INO); - if (filldir(dirent, buf, len, pos, ino, DT_DIR < 0)) { + if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { /* returning this tgid failed, save it as the first * pid for the next readir call */ filp->f_version = tid; @@ -2392,3 +2296,14 @@ static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct return 0; } + +static struct inode_operations proc_task_inode_operations = { + .lookup = proc_task_lookup, + .getattr = proc_task_getattr, + .setattr = proc_setattr, +}; + +static struct file_operations proc_task_operations = { + .read = generic_read_dir, + .readdir = proc_task_readdir, +}; diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 5bbd6089605..8d88e58ed5c 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -45,6 +45,7 @@ #include <linux/sysrq.h> #include <linux/vmalloc.h> #include <linux/crash_dump.h> +#include <linux/pspace.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/io.h> @@ -91,7 +92,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off, LOAD_INT(a), LOAD_FRAC(a), LOAD_INT(b), LOAD_FRAC(b), LOAD_INT(c), LOAD_FRAC(c), - nr_running(), nr_threads, last_pid); + nr_running(), nr_threads, init_pspace.last_pid); return proc_calc_metrics(page, start, off, count, eof, len); } @@ -277,12 +278,15 @@ static int devinfo_show(struct seq_file *f, void *v) if (i == 0) seq_printf(f, "Character devices:\n"); chrdev_show(f, i); - } else { + } +#ifdef CONFIG_BLOCK + else { i -= CHRDEV_MAJOR_HASH_SIZE; if (i == 0) seq_printf(f, "\nBlock devices:\n"); blkdev_show(f, i); } +#endif return 0; } @@ -355,6 +359,7 @@ static int stram_read_proc(char *page, char **start, off_t off, } #endif +#ifdef CONFIG_BLOCK extern struct seq_operations partitions_op; static int partitions_open(struct inode *inode, struct file *file) { @@ -378,6 +383,7 @@ static struct file_operations proc_diskstats_operations = { .llseek = seq_lseek, .release = seq_release, }; +#endif #ifdef CONFIG_MODULES extern struct seq_operations modules_op; @@ -695,7 +701,9 @@ void __init proc_misc_init(void) entry->proc_fops = &proc_kmsg_operations; create_seq_entry("devices", 0, &proc_devinfo_operations); create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); +#ifdef CONFIG_BLOCK create_seq_entry("partitions", 0, &proc_partitions_operations); +#endif create_seq_entry("stat", 0, &proc_stat_operations); create_seq_entry("interrupts", 0, &proc_interrupts_operations); #ifdef CONFIG_SLAB @@ -707,7 +715,9 @@ void __init proc_misc_init(void) create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); +#ifdef CONFIG_BLOCK create_seq_entry("diskstats", 0, &proc_diskstats_operations); +#endif #ifdef CONFIG_MODULES create_seq_entry("modules", 0, &proc_modules_operations); #endif diff --git a/fs/proc/root.c b/fs/proc/root.c index 8901c65caca..ffe66c38488 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/bitops.h> #include <linux/smp_lock.h> +#include <linux/mount.h> #include "internal.h" @@ -28,6 +29,17 @@ struct proc_dir_entry *proc_sys_root; static int proc_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { + if (proc_mnt) { + /* Seed the root directory with a pid so it doesn't need + * to be special in base.c. I would do this earlier but + * the only task alive when /proc is mounted the first time + * is the init_task and it doesn't have any pids. + */ + struct proc_inode *ei; + ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode); + if (!ei->pid) + ei->pid = find_get_pid(1); + } return get_sb_single(fs_type, flags, data, proc_fill_super, mnt); } diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c index 62af4b1348b..467e5ac7280 100644 --- a/fs/qnx4/file.c +++ b/fs/qnx4/file.c @@ -22,11 +22,13 @@ const struct file_operations qnx4_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, #ifdef CONFIG_QNX4FS_RW - .write = generic_file_write, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .fsync = qnx4_sync_file, #endif }; diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c index c3d83f67154..733cdf01d64 100644 --- a/fs/qnx4/namei.c +++ b/fs/qnx4/namei.c @@ -186,11 +186,10 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry) memset(de->di_fname, 0, sizeof de->di_fname); de->di_mode = 0; mark_buffer_dirty(bh); - inode->i_nlink = 0; + clear_nlink(inode); mark_inode_dirty(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; - dir->i_nlink--; - mark_inode_dirty(dir); + inode_dec_link_count(dir); retval = 0; end_rmdir: @@ -234,9 +233,8 @@ int qnx4_unlink(struct inode *dir, struct dentry *dentry) mark_buffer_dirty(bh); dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); - inode->i_nlink--; inode->i_ctime = dir->i_ctime; - mark_inode_dirty(inode); + inode_dec_link_count(inode); retval = 0; end_unlink: diff --git a/fs/quota.c b/fs/quota.c index d6a2be826e2..b9dae76a0b6 100644 --- a/fs/quota.c +++ b/fs/quota.c @@ -338,6 +338,34 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void } /* + * look up a superblock on which quota ops will be performed + * - use the name of a block device to find the superblock thereon + */ +static inline struct super_block *quotactl_block(const char __user *special) +{ +#ifdef CONFIG_BLOCK + struct block_device *bdev; + struct super_block *sb; + char *tmp = getname(special); + + if (IS_ERR(tmp)) + return ERR_PTR(PTR_ERR(tmp)); + bdev = lookup_bdev(tmp); + putname(tmp); + if (IS_ERR(bdev)) + return ERR_PTR(PTR_ERR(bdev)); + sb = get_super(bdev); + bdput(bdev); + if (!sb) + return ERR_PTR(-ENODEV); + + return sb; +#else + return ERR_PTR(-ENODEV); +#endif +} + +/* * This is the system call interface. This communicates with * the user-level programs. Currently this only supports diskquota * calls. Maybe we need to add the process quotas etc. in the future, @@ -347,25 +375,15 @@ asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t { uint cmds, type; struct super_block *sb = NULL; - struct block_device *bdev; - char *tmp; int ret; cmds = cmd >> SUBCMDSHIFT; type = cmd & SUBCMDMASK; if (cmds != Q_SYNC || special) { - tmp = getname(special); - if (IS_ERR(tmp)) - return PTR_ERR(tmp); - bdev = lookup_bdev(tmp); - putname(tmp); - if (IS_ERR(bdev)) - return PTR_ERR(bdev); - sb = get_super(bdev); - bdput(bdev); - if (!sb) - return -ENODEV; + sb = quotactl_block(special); + if (IS_ERR(sb)) + return PTR_ERR(sb); } ret = check_quotactl_valid(sb, type, cmds, id); diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 86f14cacf64..0947fb57dcf 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c @@ -33,8 +33,10 @@ const struct address_space_operations ramfs_aops = { }; const struct file_operations ramfs_file_operations = { - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = simple_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 677139b48e0..bfe5dbf1002 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -36,8 +36,10 @@ const struct address_space_operations ramfs_aops = { const struct file_operations ramfs_file_operations = { .mmap = ramfs_nommu_mmap, .get_unmapped_area = ramfs_nommu_get_unmapped_area, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .fsync = simple_sync_file, .sendfile = generic_file_sendfile, .llseek = generic_file_llseek, diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index bc0e5166242..2faf4cdf61b 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -75,7 +75,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; @@ -113,7 +113,7 @@ static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) { int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) - dir->i_nlink++; + inc_nlink(dir); return retval; } diff --git a/fs/read_write.c b/fs/read_write.c index d4cb3183c99..f792000a28e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -15,13 +15,15 @@ #include <linux/module.h> #include <linux/syscalls.h> #include <linux/pagemap.h> +#include "read_write.h" #include <asm/uaccess.h> #include <asm/unistd.h> const struct file_operations generic_ro_fops = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .mmap = generic_file_readonly_mmap, .sendfile = generic_file_sendfile, }; @@ -227,14 +229,20 @@ static void wait_on_retry_sync_kiocb(struct kiocb *iocb) ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) { + struct iovec iov = { .iov_base = buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; - while (-EIOCBRETRY == - (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos))) + kiocb.ki_left = len; + + for (;;) { + ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); + if (ret != -EIOCBRETRY) + break; wait_on_retry_sync_kiocb(&kiocb); + } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); @@ -279,14 +287,20 @@ EXPORT_SYMBOL(vfs_read); ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { + struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; - while (-EIOCBRETRY == - (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos))) + kiocb.ki_left = len; + + for (;;) { + ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); + if (ret != -EIOCBRETRY) + break; wait_on_retry_sync_kiocb(&kiocb); + } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); @@ -438,78 +452,155 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */ +ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, + unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) +{ + struct kiocb kiocb; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = *ppos; + kiocb.ki_left = len; + kiocb.ki_nbytes = len; + + for (;;) { + ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); + if (ret != -EIOCBRETRY) + break; + wait_on_retry_sync_kiocb(&kiocb); + } + + if (ret == -EIOCBQUEUED) + ret = wait_on_sync_kiocb(&kiocb); + *ppos = kiocb.ki_pos; + return ret; +} + +/* Do it by hand, with file-ops */ +ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, + unsigned long nr_segs, loff_t *ppos, io_fn_t fn) +{ + struct iovec *vector = iov; + ssize_t ret = 0; + + while (nr_segs > 0) { + void __user *base; + size_t len; + ssize_t nr; + + base = vector->iov_base; + len = vector->iov_len; + vector++; + nr_segs--; + + nr = fn(filp, base, len, ppos); + + if (nr < 0) { + if (!ret) + ret = nr; + break; + } + ret += nr; + if (nr != len) + break; + } + + return ret; +} + /* A write operation does a read from user space and vice versa */ #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) +ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, + unsigned long nr_segs, unsigned long fast_segs, + struct iovec *fast_pointer, + struct iovec **ret_pointer) + { + unsigned long seg; + ssize_t ret; + struct iovec *iov = fast_pointer; + + /* + * SuS says "The readv() function *may* fail if the iovcnt argument + * was less than or equal to 0, or greater than {IOV_MAX}. Linux has + * traditionally returned zero for zero segments, so... + */ + if (nr_segs == 0) { + ret = 0; + goto out; + } + + /* + * First get the "struct iovec" from user memory and + * verify all the pointers + */ + if (nr_segs > UIO_MAXIOV) { + ret = -EINVAL; + goto out; + } + if (nr_segs > fast_segs) { + iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); + if (iov == NULL) { + ret = -ENOMEM; + goto out; + } + } + if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) { + ret = -EFAULT; + goto out; + } + + /* + * According to the Single Unix Specification we should return EINVAL + * if an element length is < 0 when cast to ssize_t or if the + * total length would overflow the ssize_t return value of the + * system call. + */ + ret = 0; + for (seg = 0; seg < nr_segs; seg++) { + void __user *buf = iov[seg].iov_base; + ssize_t len = (ssize_t)iov[seg].iov_len; + + /* see if we we're about to use an invalid len or if + * it's about to overflow ssize_t */ + if (len < 0 || (ret + len < ret)) { + ret = -EINVAL; + goto out; + } + if (unlikely(!access_ok(vrfy_dir(type), buf, len))) { + ret = -EFAULT; + goto out; + } + + ret += len; + } +out: + *ret_pointer = iov; + return ret; +} + static ssize_t do_readv_writev(int type, struct file *file, const struct iovec __user * uvector, unsigned long nr_segs, loff_t *pos) { - typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); - typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); - size_t tot_len; struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov=iovstack, *vector; + struct iovec *iov = iovstack; ssize_t ret; - int seg; io_fn_t fn; iov_fn_t fnv; - /* - * SuS says "The readv() function *may* fail if the iovcnt argument - * was less than or equal to 0, or greater than {IOV_MAX}. Linux has - * traditionally returned zero for zero segments, so... - */ - ret = 0; - if (nr_segs == 0) + if (!file->f_op) { + ret = -EINVAL; goto out; + } - /* - * First get the "struct iovec" from user memory and - * verify all the pointers - */ - ret = -EINVAL; - if (nr_segs > UIO_MAXIOV) - goto out; - if (!file->f_op) - goto out; - if (nr_segs > UIO_FASTIOV) { - ret = -ENOMEM; - iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); - if (!iov) - goto out; - } - ret = -EFAULT; - if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) + ret = rw_copy_check_uvector(type, uvector, nr_segs, + ARRAY_SIZE(iovstack), iovstack, &iov); + if (ret <= 0) goto out; - /* - * Single unix specification: - * We should -EINVAL if an element length is not >= 0 and fitting an - * ssize_t. The total length is fitting an ssize_t - * - * Be careful here because iov_len is a size_t not an ssize_t - */ - tot_len = 0; - ret = -EINVAL; - for (seg = 0; seg < nr_segs; seg++) { - void __user *buf = iov[seg].iov_base; - ssize_t len = (ssize_t)iov[seg].iov_len; - - if (len < 0) /* size_t not fitting an ssize_t .. */ - goto out; - if (unlikely(!access_ok(vrfy_dir(type), buf, len))) - goto Efault; - tot_len += len; - if ((ssize_t)tot_len < 0) /* maths overflow on the ssize_t */ - goto out; - } - if (tot_len == 0) { - ret = 0; - goto out; - } - + tot_len = ret; ret = rw_verify_area(type, file, pos, tot_len); if (ret < 0) goto out; @@ -520,39 +611,18 @@ static ssize_t do_readv_writev(int type, struct file *file, fnv = NULL; if (type == READ) { fn = file->f_op->read; - fnv = file->f_op->readv; + fnv = file->f_op->aio_read; } else { fn = (io_fn_t)file->f_op->write; - fnv = file->f_op->writev; + fnv = file->f_op->aio_write; } - if (fnv) { - ret = fnv(file, iov, nr_segs, pos); - goto out; - } - - /* Do it by hand, with file-ops */ - ret = 0; - vector = iov; - while (nr_segs > 0) { - void __user * base; - size_t len; - ssize_t nr; - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - nr = fn(file, base, len, pos); + if (fnv) + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, + pos, fnv); + else + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); - if (nr < 0) { - if (!ret) ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } out: if (iov != iovstack) kfree(iov); @@ -563,9 +633,6 @@ out: fsnotify_modify(file->f_dentry); } return ret; -Efault: - ret = -EFAULT; - goto out; } ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, @@ -573,7 +640,7 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, { if (!(file->f_mode & FMODE_READ)) return -EBADF; - if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) return -EINVAL; return do_readv_writev(READ, file, vec, vlen, pos); @@ -586,7 +653,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, { if (!(file->f_mode & FMODE_WRITE)) return -EBADF; - if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) return -EINVAL; return do_readv_writev(WRITE, file, vec, vlen, pos); diff --git a/fs/read_write.h b/fs/read_write.h new file mode 100644 index 00000000000..d07b954c6e0 --- /dev/null +++ b/fs/read_write.h @@ -0,0 +1,14 @@ +/* + * This file is only for sharing some helpers from read_write.c with compat.c. + * Don't use anywhere else. + */ + + +typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); +typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *, + unsigned long, loff_t); + +ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, + unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); +ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, + unsigned long nr_segs, loff_t *ppos, io_fn_t fn); diff --git a/fs/readdir.c b/fs/readdir.c index b6109329b60..bff3ee58e2f 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -69,20 +69,24 @@ struct readdir_callback { }; static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, - ino_t ino, unsigned int d_type) + u64 ino, unsigned int d_type) { struct readdir_callback * buf = (struct readdir_callback *) __buf; struct old_linux_dirent __user * dirent; + unsigned long d_ino; if (buf->result) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; buf->result++; dirent = buf->dirent; if (!access_ok(VERIFY_WRITE, dirent, (unsigned long)(dirent->d_name + namlen + 1) - (unsigned long)dirent)) goto efault; - if ( __put_user(ino, &dirent->d_ino) || + if ( __put_user(d_ino, &dirent->d_ino) || __put_user(offset, &dirent->d_offset) || __put_user(namlen, &dirent->d_namlen) || __copy_to_user(dirent->d_name, name, namlen) || @@ -138,22 +142,26 @@ struct getdents_callback { }; static int filldir(void * __buf, const char * name, int namlen, loff_t offset, - ino_t ino, unsigned int d_type) + u64 ino, unsigned int d_type) { struct linux_dirent __user * dirent; struct getdents_callback * buf = (struct getdents_callback *) __buf; + unsigned long d_ino; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; dirent = buf->previous; if (dirent) { if (__put_user(offset, &dirent->d_off)) goto efault; } dirent = buf->current_dir; - if (__put_user(ino, &dirent->d_ino)) + if (__put_user(d_ino, &dirent->d_ino)) goto efault; if (__put_user(reclen, &dirent->d_reclen)) goto efault; @@ -222,7 +230,7 @@ struct getdents_callback64 { }; static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, - ino_t ino, unsigned int d_type) + u64 ino, unsigned int d_type) { struct linux_dirent64 __user *dirent; struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 4a7dbdee1b6..1bfae42117c 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -9,6 +9,7 @@ #include <linux/buffer_head.h> #include <linux/kernel.h> #include <linux/pagemap.h> +#include <linux/vmalloc.h> #include <linux/reiserfs_fs_sb.h> #include <linux/reiserfs_fs_i.h> #include <linux/quotaops.h> @@ -50,16 +51,15 @@ static inline void get_bit_address(struct super_block *s, { /* It is in the bitmap block number equal to the block * number divided by the number of bits in a block. */ - *bmap_nr = block / (s->s_blocksize << 3); + *bmap_nr = block >> (s->s_blocksize_bits + 3); /* Within that bitmap block it is located at bit offset *offset. */ *offset = block & ((s->s_blocksize << 3) - 1); - return; } #ifdef CONFIG_REISERFS_CHECK int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) { - int i, j; + int bmap, offset; if (block == 0 || block >= SB_BLOCK_COUNT(s)) { reiserfs_warning(s, @@ -68,36 +68,32 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) return 0; } - /* it can't be one of the bitmap blocks */ - for (i = 0; i < SB_BMAP_NR(s); i++) - if (block == SB_AP_BITMAP(s)[i].bh->b_blocknr) { + get_bit_address(s, block, &bmap, &offset); + + /* Old format filesystem? Unlikely, but the bitmaps are all up front so + * we need to account for it. */ + if (unlikely(test_bit(REISERFS_OLD_FORMAT, + &(REISERFS_SB(s)->s_properties)))) { + b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; + if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) { + reiserfs_warning(s, "vs: 4019: is_reusable: " + "bitmap block %lu(%u) can't be freed or reused", + block, SB_BMAP_NR(s)); + return 0; + } + } else { + if (offset == 0) { reiserfs_warning(s, "vs: 4020: is_reusable: " "bitmap block %lu(%u) can't be freed or reused", block, SB_BMAP_NR(s)); return 0; } - - get_bit_address(s, block, &i, &j); - - if (i >= SB_BMAP_NR(s)) { - reiserfs_warning(s, - "vs-4030: is_reusable: there is no so many bitmap blocks: " - "block=%lu, bitmap_nr=%d", block, i); - return 0; } - if ((bit_value == 0 && - reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) || - (bit_value == 1 && - reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) { + if (bmap >= SB_BMAP_NR(s)) { reiserfs_warning(s, - "vs-4040: is_reusable: corresponding bit of block %lu does not " - "match required value (i==%d, j==%d) test_bit==%d", - block, i, j, reiserfs_test_le_bit(j, - SB_AP_BITMAP - (s)[i].bh-> - b_data)); - + "vs-4030: is_reusable: there is no so many bitmap blocks: " + "block=%lu, bitmap_nr=%d", block, bmap); return 0; } @@ -141,6 +137,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, { struct super_block *s = th->t_super; struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; + struct buffer_head *bh; int end, next; int org = *beg; @@ -159,22 +156,25 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, bmap_n); return 0; } - if (buffer_locked(bi->bh)) { - PROC_INFO_INC(s, scan_bitmap.wait); - __wait_on_buffer(bi->bh); - } + + bh = reiserfs_read_bitmap_block(s, bmap_n); + if (bh == NULL) + return 0; while (1) { cont: - if (bi->free_count < min) + if (bi->free_count < min) { + brelse(bh); return 0; // No free blocks in this bitmap + } /* search for a first zero bit -- beggining of a window */ *beg = reiserfs_find_next_zero_le_bit - ((unsigned long *)(bi->bh->b_data), boundary, *beg); + ((unsigned long *)(bh->b_data), boundary, *beg); if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block * cannot contain a zero window of minimum size */ + brelse(bh); return 0; } @@ -183,7 +183,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, /* first zero bit found; we check next bits */ for (end = *beg + 1;; end++) { if (end >= *beg + max || end >= boundary - || reiserfs_test_le_bit(end, bi->bh->b_data)) { + || reiserfs_test_le_bit(end, bh->b_data)) { next = end; break; } @@ -197,12 +197,12 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, * (end) points to one bit after the window end */ if (end - *beg >= min) { /* it seems we have found window of proper size */ int i; - reiserfs_prepare_for_journal(s, bi->bh, 1); + reiserfs_prepare_for_journal(s, bh, 1); /* try to set all blocks used checking are they still free */ for (i = *beg; i < end; i++) { /* It seems that we should not check in journal again. */ if (reiserfs_test_and_set_le_bit - (i, bi->bh->b_data)) { + (i, bh->b_data)) { /* bit was set by another process * while we slept in prepare_for_journal() */ PROC_INFO_INC(s, scan_bitmap.stolen); @@ -214,17 +214,16 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, /* otherwise we clear all bit were set ... */ while (--i >= *beg) reiserfs_test_and_clear_le_bit - (i, bi->bh->b_data); - reiserfs_restore_prepared_buffer(s, - bi-> - bh); + (i, bh->b_data); + reiserfs_restore_prepared_buffer(s, bh); *beg = org; /* ... and search again in current block from beginning */ goto cont; } } bi->free_count -= (end - *beg); - journal_mark_dirty(th, s, bi->bh); + journal_mark_dirty(th, s, bh); + brelse(bh); /* free block count calculation */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), @@ -266,9 +265,20 @@ static int bmap_hash_id(struct super_block *s, u32 id) */ static inline int block_group_used(struct super_block *s, u32 id) { - int bm; - bm = bmap_hash_id(s, id); - if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) { + int bm = bmap_hash_id(s, id); + struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm]; + + /* If we don't have cached information on this bitmap block, we're + * going to have to load it later anyway. Loading it here allows us + * to make a better decision. This favors long-term performace gain + * with a better on-disk layout vs. a short term gain of skipping the + * read and potentially having a bad placement. */ + if (info->first_zero_hint == 0) { + struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); + brelse(bh); + } + + if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) { return 0; } return 1; @@ -373,7 +383,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, { struct super_block *s = th->t_super; struct reiserfs_super_block *rs; - struct buffer_head *sbh; + struct buffer_head *sbh, *bmbh; struct reiserfs_bitmap_info *apbi; int nr, offset; @@ -394,16 +404,21 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, return; } - reiserfs_prepare_for_journal(s, apbi[nr].bh, 1); + bmbh = reiserfs_read_bitmap_block(s, nr); + if (!bmbh) + return; + + reiserfs_prepare_for_journal(s, bmbh, 1); /* clear bit for the given block in bit map */ - if (!reiserfs_test_and_clear_le_bit(offset, apbi[nr].bh->b_data)) { + if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) { reiserfs_warning(s, "vs-4080: reiserfs_free_block: " "free_block (%s:%lu)[dev:blocknr]: bit already cleared", reiserfs_bdevname(s), block); } apbi[nr].free_count++; - journal_mark_dirty(th, s, apbi[nr].bh); + journal_mark_dirty(th, s, bmbh); + brelse(bmbh); reiserfs_prepare_for_journal(s, sbh, 1); /* update super block */ @@ -1019,7 +1034,6 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1; int passno = 0; int nr_allocated = 0; - int bigalloc = 0; determine_prealloc_size(hint); if (!hint->formatted_node) { @@ -1046,28 +1060,9 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start hint->preallocate = hint->prealloc_size = 0; } /* for unformatted nodes, force large allocations */ - bigalloc = amount_needed; } do { - /* in bigalloc mode, nr_allocated should stay zero until - * the entire allocation is filled - */ - if (unlikely(bigalloc && nr_allocated)) { - reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n", - bigalloc, nr_allocated); - /* reset things to a sane value */ - bigalloc = amount_needed - nr_allocated; - } - /* - * try pass 0 and pass 1 looking for a nice big - * contiguous allocation. Then reset and look - * for anything you can find. - */ - if (passno == 2 && bigalloc) { - passno = 0; - bigalloc = 0; - } switch (passno++) { case 0: /* Search from hint->search_start to end of disk */ start = hint->search_start; @@ -1105,8 +1100,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start new_blocknrs + nr_allocated, start, finish, - bigalloc ? - bigalloc : 1, + 1, amount_needed - nr_allocated, hint-> @@ -1263,3 +1257,89 @@ int reiserfs_can_fit_pages(struct super_block *sb /* superblock of filesystem return space > 0 ? space : 0; } + +void reiserfs_cache_bitmap_metadata(struct super_block *sb, + struct buffer_head *bh, + struct reiserfs_bitmap_info *info) +{ + unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); + + info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3); + + while (--cur >= (unsigned long *)bh->b_data) { + int base = ((char *)cur - bh->b_data) << 3; + + /* 0 and ~0 are special, we can optimize for them */ + if (*cur == 0) { + info->first_zero_hint = base; + info->free_count += BITS_PER_LONG; + } else if (*cur != ~0L) { /* A mix, investigate */ + int b; + for (b = BITS_PER_LONG - 1; b >= 0; b--) { + if (!reiserfs_test_le_bit(b, cur)) { + info->first_zero_hint = base + b; + info->free_count++; + } + } + } + } + /* The first bit must ALWAYS be 1 */ + BUG_ON(info->first_zero_hint == 0); +} + +struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, + unsigned int bitmap) +{ + b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; + struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap; + struct buffer_head *bh; + + /* Way old format filesystems had the bitmaps packed up front. + * I doubt there are any of these left, but just in case... */ + if (unlikely(test_bit(REISERFS_OLD_FORMAT, + &(REISERFS_SB(sb)->s_properties)))) + block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap; + else if (bitmap == 0) + block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; + + bh = sb_bread(sb, block); + if (bh == NULL) + reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) " + "reading failed", __FUNCTION__, bh->b_blocknr); + else { + if (buffer_locked(bh)) { + PROC_INFO_INC(sb, scan_bitmap.wait); + __wait_on_buffer(bh); + } + BUG_ON(!buffer_uptodate(bh)); + BUG_ON(atomic_read(&bh->b_count) == 0); + + if (info->first_zero_hint == 0) + reiserfs_cache_bitmap_metadata(sb, bh, info); + } + + return bh; +} + +int reiserfs_init_bitmap_cache(struct super_block *sb) +{ + struct reiserfs_bitmap_info *bitmap; + + bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); + if (bitmap == NULL) + return -ENOMEM; + + memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); + + SB_AP_BITMAP(sb) = bitmap; + + return 0; +} + +void reiserfs_free_bitmap_cache(struct super_block *sb) +{ + if (SB_AP_BITMAP(sb)) { + vfree(SB_AP_BITMAP(sb)); + SB_AP_BITMAP(sb) = NULL; + } +} diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 9aabcc0ccd2..657050ad743 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -22,6 +22,9 @@ const struct file_operations reiserfs_dir_operations = { .readdir = reiserfs_readdir, .fsync = reiserfs_dir_fsync, .ioctl = reiserfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = reiserfs_compat_ioctl, +#endif }; static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 1cfbe857ba2..41f24369e47 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -2,6 +2,7 @@ * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ +#include <linux/config.h> #include <linux/time.h> #include <linux/reiserfs_fs.h> #include <linux/reiserfs_acl.h> @@ -1333,7 +1334,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t if (err) return err; } - result = generic_file_write(file, buf, count, ppos); + result = do_sync_write(file, buf, count, ppos); if (after_file_end) { /* Now update i_size and remove the savelink */ struct reiserfs_transaction_handle th; @@ -1565,10 +1566,14 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t } const struct file_operations reiserfs_file_operations = { - .read = generic_file_read, + .read = do_sync_read, .write = reiserfs_file_write, .ioctl = reiserfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = reiserfs_compat_ioctl, +#endif .mmap = generic_file_mmap, + .open = generic_file_open, .release = reiserfs_file_release, .fsync = reiserfs_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index a986b5e1e28..9c57578cb83 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -9,6 +9,7 @@ #include <asm/uaccess.h> #include <linux/pagemap.h> #include <linux/smp_lock.h> +#include <linux/compat.h> static int reiserfs_unpack(struct inode *inode, struct file *filp); @@ -94,6 +95,40 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, } } +#ifdef CONFIG_COMPAT +long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + /* These are just misnamed, they actually get/put from/to user an int */ + switch (cmd) { + case REISERFS_IOC32_UNPACK: + cmd = REISERFS_IOC_UNPACK; + break; + case REISERFS_IOC32_GETFLAGS: + cmd = REISERFS_IOC_GETFLAGS; + break; + case REISERFS_IOC32_SETFLAGS: + cmd = REISERFS_IOC_SETFLAGS; + break; + case REISERFS_IOC32_GETVERSION: + cmd = REISERFS_IOC_GETVERSION; + break; + case REISERFS_IOC32_SETVERSION: + cmd = REISERFS_IOC_SETVERSION; + break; + default: + return -ENOIOCTLCMD; + } + lock_kernel(); + ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); + unlock_kernel(); + return ret; +} +#endif + /* ** reiserfs_unpack ** Function try to convert tail from direct item into indirect. diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c61710e49c6..16e9cff8f15 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -19,8 +19,8 @@ #include <linux/smp_lock.h> #include <linux/quotaops.h> -#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } -#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--; +#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } +#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i); // directory item contains array of entry headers. This performs // binary search through that array @@ -913,7 +913,7 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) reiserfs_warning(inode->i_sb, "%s: empty directory has nlink " "!= 2 (%d)", __FUNCTION__, inode->i_nlink); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; reiserfs_update_sd(&th, inode); @@ -994,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) inode->i_nlink = 1; } - inode->i_nlink--; + drop_nlink(inode); /* * we schedule before doing the add_save_link call, save the link @@ -1006,7 +1006,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL, 0); if (retval < 0) { - inode->i_nlink++; + inc_nlink(inode); goto end_unlink; } inode->i_ctime = CURRENT_TIME_SEC; @@ -1143,7 +1143,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, } /* inc before scheduling so reiserfs_unlink knows we are here */ - inode->i_nlink++; + inc_nlink(inode); retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) { @@ -1473,9 +1473,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dentry_inode) { // adjust link number of the victim if (S_ISDIR(new_dentry_inode->i_mode)) { - new_dentry_inode->i_nlink = 0; + clear_nlink(new_dentry_inode); } else { - new_dentry_inode->i_nlink--; + drop_nlink(new_dentry_inode); } new_dentry_inode->i_ctime = ctime; savelink = new_dentry_inode->i_nlink; diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 39cc7f47f5d..315684793d1 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -22,6 +22,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) int err = 0; struct reiserfs_super_block *sb; struct reiserfs_bitmap_info *bitmap; + struct reiserfs_bitmap_info *info; struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s); struct buffer_head *bh; struct reiserfs_transaction_handle th; @@ -127,16 +128,20 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) * transaction begins, and the new bitmaps don't matter if the * transaction fails. */ for (i = bmap_nr; i < bmap_nr_new; i++) { - bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8); - memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb)); - reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data); - - set_buffer_uptodate(bitmap[i].bh); - mark_buffer_dirty(bitmap[i].bh); - sync_dirty_buffer(bitmap[i].bh); + /* don't use read_bitmap_block since it will cache + * the uninitialized bitmap */ + bh = sb_bread(s, i * s->s_blocksize * 8); + memset(bh->b_data, 0, sb_blocksize(sb)); + reiserfs_test_and_set_le_bit(0, bh->b_data); + reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + sync_dirty_buffer(bh); // update bitmap_info stuff bitmap[i].first_zero_hint = 1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; + brelse(bh); } /* free old bitmap blocks array */ SB_AP_BITMAP(s) = bitmap; @@ -150,30 +155,46 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) if (err) return err; - /* correct last bitmap blocks in old and new disk layout */ - reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1); + /* Extend old last bitmap block - new blocks have been made available */ + info = SB_AP_BITMAP(s) + bmap_nr - 1; + bh = reiserfs_read_bitmap_block(s, bmap_nr - 1); + if (!bh) { + int jerr = journal_end(&th, s, 10); + if (jerr) + return jerr; + return -EIO; + } + + reiserfs_prepare_for_journal(s, bh, 1); for (i = block_r; i < s->s_blocksize * 8; i++) - reiserfs_test_and_clear_le_bit(i, - SB_AP_BITMAP(s)[bmap_nr - - 1].bh->b_data); - SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r; - if (!SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint) - SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r; + reiserfs_test_and_clear_le_bit(i, bh->b_data); + info->free_count += s->s_blocksize * 8 - block_r; + if (!info->first_zero_hint) + info->first_zero_hint = block_r; - journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh); + journal_mark_dirty(&th, s, bh); + brelse(bh); + + /* Correct new last bitmap block - It may not be full */ + info = SB_AP_BITMAP(s) + bmap_nr_new - 1; + bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1); + if (!bh) { + int jerr = journal_end(&th, s, 10); + if (jerr) + return jerr; + return -EIO; + } - reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1); + reiserfs_prepare_for_journal(s, bh, 1); for (i = block_r_new; i < s->s_blocksize * 8; i++) - reiserfs_test_and_set_le_bit(i, - SB_AP_BITMAP(s)[bmap_nr_new - - 1].bh->b_data); - journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh); + reiserfs_test_and_set_le_bit(i, bh->b_data); + journal_mark_dirty(&th, s, bh); + brelse(bh); - SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= - s->s_blocksize * 8 - block_r_new; + info->free_count -= s->s_blocksize * 8 - block_r_new; /* Extreme case where last bitmap is the only valid block in itself. */ - if (!SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count) - SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0; + if (!info->free_count) + info->first_zero_hint = 0; /* update super */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); free_blocks = SB_FREE_BLOCKS(s); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 80fc3b32802..c89aa233819 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -432,7 +432,6 @@ int remove_save_link(struct inode *inode, int truncate) static void reiserfs_put_super(struct super_block *s) { - int i; struct reiserfs_transaction_handle th; th.t_trans_id = 0; @@ -462,10 +461,7 @@ static void reiserfs_put_super(struct super_block *s) */ journal_release(&th, s); - for (i = 0; i < SB_BMAP_NR(s); i++) - brelse(SB_AP_BITMAP(s)[i].bh); - - vfree(SB_AP_BITMAP(s)); + reiserfs_free_bitmap_cache(s); brelse(SB_BUFFER_WITH_SB(s)); @@ -1243,118 +1239,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) return 0; } -/* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk. - * @sb - superblock for this filesystem - * @bi - the bitmap info to be loaded. Requires that bi->bh is valid. - * - * This routine counts how many free bits there are, finding the first zero - * as a side effect. Could also be implemented as a loop of test_bit() calls, or - * a loop of find_first_zero_bit() calls. This implementation is similar to - * find_first_zero_bit(), but doesn't return after it finds the first bit. - * Should only be called on fs mount, but should be fairly efficient anyways. - * - * bi->first_zero_hint is considered unset if it == 0, since the bitmap itself - * will * invariably occupt block 0 represented in the bitmap. The only - * exception to this is when free_count also == 0, since there will be no - * free blocks at all. - */ - -static void load_bitmap_info_data(struct super_block *sb, - struct reiserfs_bitmap_info *bi) -{ - unsigned long *cur = (unsigned long *)bi->bh->b_data; - - while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) { - - /* No need to scan if all 0's or all 1's. - * Since we're only counting 0's, we can simply ignore all 1's */ - if (*cur == 0) { - if (bi->first_zero_hint == 0) { - bi->first_zero_hint = - ((char *)cur - bi->bh->b_data) << 3; - } - bi->free_count += sizeof(unsigned long) * 8; - } else if (*cur != ~0L) { - int b; - for (b = 0; b < sizeof(unsigned long) * 8; b++) { - if (!reiserfs_test_le_bit(b, cur)) { - bi->free_count++; - if (bi->first_zero_hint == 0) - bi->first_zero_hint = - (((char *)cur - - bi->bh->b_data) << 3) + b; - } - } - } - cur++; - } - -#ifdef CONFIG_REISERFS_CHECK -// This outputs a lot of unneded info on big FSes -// reiserfs_warning ("bitmap loaded from block %d: %d free blocks", -// bi->bh->b_blocknr, bi->free_count); -#endif -} - -static int read_bitmaps(struct super_block *s) -{ - int i, bmap_nr; - - SB_AP_BITMAP(s) = - vmalloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s)); - if (SB_AP_BITMAP(s) == 0) - return 1; - memset(SB_AP_BITMAP(s), 0, - sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s)); - for (i = 0, bmap_nr = - REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1; - i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) { - SB_AP_BITMAP(s)[i].bh = sb_getblk(s, bmap_nr); - if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) - ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh); - } - for (i = 0; i < SB_BMAP_NR(s); i++) { - wait_on_buffer(SB_AP_BITMAP(s)[i].bh); - if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) { - reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: " - "bitmap block (#%lu) reading failed", - SB_AP_BITMAP(s)[i].bh->b_blocknr); - for (i = 0; i < SB_BMAP_NR(s); i++) - brelse(SB_AP_BITMAP(s)[i].bh); - vfree(SB_AP_BITMAP(s)); - SB_AP_BITMAP(s) = NULL; - return 1; - } - load_bitmap_info_data(s, SB_AP_BITMAP(s) + i); - } - return 0; -} - -static int read_old_bitmaps(struct super_block *s) -{ - int i; - struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s); - int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ - - /* read true bitmap */ - SB_AP_BITMAP(s) = - vmalloc(sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs)); - if (SB_AP_BITMAP(s) == 0) - return 1; - - memset(SB_AP_BITMAP(s), 0, - sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs)); - - for (i = 0; i < sb_bmap_nr(rs); i++) { - SB_AP_BITMAP(s)[i].bh = sb_bread(s, bmp1 + i); - if (!SB_AP_BITMAP(s)[i].bh) - return 1; - load_bitmap_info_data(s, SB_AP_BITMAP(s) + i); - } - - return 0; -} - static int read_super_block(struct super_block *s, int offset) { struct buffer_head *bh; @@ -1456,7 +1340,6 @@ static int read_super_block(struct super_block *s, int offset) /* after journal replay, reread all bitmap and super blocks */ static int reread_meta_blocks(struct super_block *s) { - int i; ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); wait_on_buffer(SB_BUFFER_WITH_SB(s)); if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { @@ -1465,20 +1348,7 @@ static int reread_meta_blocks(struct super_block *s) return 1; } - for (i = 0; i < SB_BMAP_NR(s); i++) { - ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)); - wait_on_buffer(SB_AP_BITMAP(s)[i].bh); - if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) { - reiserfs_warning(s, - "reread_meta_blocks, error reading bitmap block number %d at %llu", - i, - (unsigned long long)SB_AP_BITMAP(s)[i]. - bh->b_blocknr); - return 1; - } - } return 0; - } ///////////////////////////////////////////////////// @@ -1659,7 +1529,6 @@ static int function2code(hashf_t func) static int reiserfs_fill_super(struct super_block *s, void *data, int silent) { struct inode *root_inode; - int j; struct reiserfs_transaction_handle th; int old_format = 0; unsigned long blocks; @@ -1736,7 +1605,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) sbi->s_mount_state = SB_REISERFS_STATE(s); sbi->s_mount_state = REISERFS_VALID_FS; - if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { + if ((errval = reiserfs_init_bitmap_cache(s))) { SWARN(silent, s, "jmacd-8: reiserfs_fill_super: unable to read bitmap"); goto error; @@ -1818,6 +1687,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) if (is_reiserfs_3_5(rs) || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1)) set_bit(REISERFS_3_5, &(sbi->s_properties)); + else if (old_format) + set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties)); else set_bit(REISERFS_3_6, &(sbi->s_properties)); @@ -1903,19 +1774,17 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) if (jinit_done) { /* kill the commit thread, free journal ram */ journal_release_error(NULL, s); } - if (SB_DISK_SUPER_BLOCK(s)) { - for (j = 0; j < SB_BMAP_NR(s); j++) { - if (SB_AP_BITMAP(s)) - brelse(SB_AP_BITMAP(s)[j].bh); - } - vfree(SB_AP_BITMAP(s)); - } + + reiserfs_free_bitmap_cache(s); if (SB_BUFFER_WITH_SB(s)) brelse(SB_BUFFER_WITH_SB(s)); #ifdef CONFIG_QUOTA - for (j = 0; j < MAXQUOTAS; j++) { - kfree(sbi->s_qf_names[j]); - sbi->s_qf_names[j] = NULL; + { + int j; + for (j = 0; j < MAXQUOTAS; j++) { + kfree(sbi->s_qf_names[j]); + sbi->s_qf_names[j] = NULL; + } } #endif kfree(sbi); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index d935fb9394e..7bdb0ed443e 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -773,7 +773,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) static int reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct dentry *xadir = (struct dentry *)buf; @@ -851,7 +851,7 @@ struct reiserfs_chown_buf { /* XXX: If there is a better way to do this, I'd love to hear about it */ static int reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; struct dentry *xafile, *xadir = chown_buf->xadir; @@ -1036,7 +1036,7 @@ struct reiserfs_listxattr_buf { static int reiserfs_listxattr_filler(void *buf, const char *name, int namelen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; int len = 0; diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index dae67048bab..50784d13c87 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -214,13 +214,15 @@ smb_updatepage(struct file *file, struct page *page, unsigned long offset, } static ssize_t -smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) +smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { + struct file * file = iocb->ki_filp; struct dentry * dentry = file->f_dentry; ssize_t status; VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), - (unsigned long) count, (unsigned long) *ppos); + (unsigned long) iocb->ki_left, (unsigned long) pos); status = smb_revalidate_inode(dentry); if (status) { @@ -233,7 +235,7 @@ smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) (long)dentry->d_inode->i_size, dentry->d_inode->i_flags, dentry->d_inode->i_atime); - status = generic_file_read(file, buf, count, ppos); + status = generic_file_aio_read(iocb, iov, nr_segs, pos); out: return status; } @@ -317,14 +319,16 @@ const struct address_space_operations smb_file_aops = { * Write to a file (through the page cache). */ static ssize_t -smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { + struct file * file = iocb->ki_filp; struct dentry * dentry = file->f_dentry; ssize_t result; VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), - (unsigned long) count, (unsigned long) *ppos); + (unsigned long) iocb->ki_left, (unsigned long) pos); result = smb_revalidate_inode(dentry); if (result) { @@ -337,8 +341,8 @@ smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t * if (result) goto out; - if (count > 0) { - result = generic_file_write(file, buf, count, ppos); + if (iocb->ki_left > 0) { + result = generic_file_aio_write(iocb, iov, nr_segs, pos); VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", (long) file->f_pos, (long) dentry->d_inode->i_size, dentry->d_inode->i_mtime, dentry->d_inode->i_atime); @@ -402,8 +406,10 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) const struct file_operations smb_file_operations = { .llseek = remote_llseek, - .read = smb_file_read, - .write = smb_file_write, + .read = do_sync_read, + .aio_read = smb_file_aio_read, + .write = do_sync_write, + .aio_write = smb_file_aio_write, .ioctl = smb_ioctl, .mmap = smb_file_mmap, .open = smb_file_open, diff --git a/fs/splice.c b/fs/splice.c index 684bca3d3a1..13e92dd19fb 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -12,7 +12,7 @@ * Jens to support splicing to files, network, direct splicing, etc and * fixing lots of bugs. * - * Copyright (C) 2005-2006 Jens Axboe <axboe@suse.de> + * Copyright (C) 2005-2006 Jens Axboe <axboe@kernel.dk> * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org> * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu> * diff --git a/fs/stat.c b/fs/stat.c index 60a31d5e596..bca07eb2003 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -140,6 +140,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta memset(&tmp, 0, sizeof(struct __old_kernel_stat)); tmp.st_dev = old_encode_dev(stat->dev); tmp.st_ino = stat->ino; + if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) + return -EOVERFLOW; tmp.st_mode = stat->mode; tmp.st_nlink = stat->nlink; if (tmp.st_nlink != stat->nlink) @@ -210,6 +212,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) tmp.st_dev = new_encode_dev(stat->dev); #endif tmp.st_ino = stat->ino; + if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) + return -EOVERFLOW; tmp.st_mode = stat->mode; tmp.st_nlink = stat->nlink; if (tmp.st_nlink != stat->nlink) @@ -347,6 +351,8 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) tmp.st_rdev = huge_encode_dev(stat->rdev); #endif tmp.st_ino = stat->ino; + if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) + return -EOVERFLOW; #ifdef STAT64_HAS_BROKEN_ST_INO tmp.__st_ino = stat->ino; #endif diff --git a/fs/super.c b/fs/super.c index 6987824d0dc..aec99ddbe53 100644 --- a/fs/super.c +++ b/fs/super.c @@ -220,6 +220,37 @@ static int grab_super(struct super_block *s) __releases(sb_lock) return 0; } +/* + * Write out and wait upon all dirty data associated with this + * superblock. Filesystem data as well as the underlying block + * device. Takes the superblock lock. Requires a second blkdev + * flush by the caller to complete the operation. + */ +void __fsync_super(struct super_block *sb) +{ + sync_inodes_sb(sb, 0); + DQUOT_SYNC(sb); + lock_super(sb); + if (sb->s_dirt && sb->s_op->write_super) + sb->s_op->write_super(sb); + unlock_super(sb); + if (sb->s_op->sync_fs) + sb->s_op->sync_fs(sb, 1); + sync_blockdev(sb->s_bdev); + sync_inodes_sb(sb, 1); +} + +/* + * Write out and wait upon all dirty data associated with this + * superblock. Filesystem data as well as the underlying block + * device. Takes the superblock lock. + */ +int fsync_super(struct super_block *sb) +{ + __fsync_super(sb); + return sync_blockdev(sb->s_bdev); +} + /** * generic_shutdown_super - common helper for ->kill_sb() * @sb: superblock to kill @@ -540,8 +571,10 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) { int retval; +#ifdef CONFIG_BLOCK if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) return -EACCES; +#endif if (flags & MS_RDONLY) acct_auto_close(sb); shrink_dcache_sb(sb); @@ -661,6 +694,7 @@ void kill_litter_super(struct super_block *sb) EXPORT_SYMBOL(kill_litter_super); +#ifdef CONFIG_BLOCK static int set_bdev_super(struct super_block *s, void *data) { s->s_bdev = data; @@ -756,6 +790,7 @@ void kill_block_super(struct super_block *sb) } EXPORT_SYMBOL(kill_block_super); +#endif int get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, diff --git a/fs/sync.c b/fs/sync.c index 955aef04da2..1de747b5ddb 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -10,11 +10,124 @@ #include <linux/syscalls.h> #include <linux/linkage.h> #include <linux/pagemap.h> +#include <linux/quotaops.h> +#include <linux/buffer_head.h> #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ SYNC_FILE_RANGE_WAIT_AFTER) /* + * sync everything. Start out by waking pdflush, because that writes back + * all queues in parallel. + */ +static void do_sync(unsigned long wait) +{ + wakeup_pdflush(0); + sync_inodes(0); /* All mappings, inodes and their blockdevs */ + DQUOT_SYNC(NULL); + sync_supers(); /* Write the superblocks */ + sync_filesystems(0); /* Start syncing the filesystems */ + sync_filesystems(wait); /* Waitingly sync the filesystems */ + sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ + if (!wait) + printk("Emergency Sync complete\n"); + if (unlikely(laptop_mode)) + laptop_sync_completion(); +} + +asmlinkage long sys_sync(void) +{ + do_sync(1); + return 0; +} + +void emergency_sync(void) +{ + pdflush_operation(do_sync, 0); +} + +/* + * Generic function to fsync a file. + * + * filp may be NULL if called via the msync of a vma. + */ +int file_fsync(struct file *filp, struct dentry *dentry, int datasync) +{ + struct inode * inode = dentry->d_inode; + struct super_block * sb; + int ret, err; + + /* sync the inode to buffers */ + ret = write_inode_now(inode, 0); + + /* sync the superblock to buffers */ + sb = inode->i_sb; + lock_super(sb); + if (sb->s_op->write_super) + sb->s_op->write_super(sb); + unlock_super(sb); + + /* .. finally sync the buffers to disk */ + err = sync_blockdev(sb->s_bdev); + if (!ret) + ret = err; + return ret; +} + +long do_fsync(struct file *file, int datasync) +{ + int ret; + int err; + struct address_space *mapping = file->f_mapping; + + if (!file->f_op || !file->f_op->fsync) { + /* Why? We can still call filemap_fdatawrite */ + ret = -EINVAL; + goto out; + } + + ret = filemap_fdatawrite(mapping); + + /* + * We need to protect against concurrent writers, which could cause + * livelocks in fsync_buffers_list(). + */ + mutex_lock(&mapping->host->i_mutex); + err = file->f_op->fsync(file, file->f_dentry, datasync); + if (!ret) + ret = err; + mutex_unlock(&mapping->host->i_mutex); + err = filemap_fdatawait(mapping); + if (!ret) + ret = err; +out: + return ret; +} + +static long __do_fsync(unsigned int fd, int datasync) +{ + struct file *file; + int ret = -EBADF; + + file = fget(fd); + if (file) { + ret = do_fsync(file, datasync); + fput(file); + } + return ret; +} + +asmlinkage long sys_fsync(unsigned int fd) +{ + return __do_fsync(fd, 0); +} + +asmlinkage long sys_fdatasync(unsigned int fd) +{ + return __do_fsync(fd, 1); +} + +/* * sys_sync_file_range() permits finely controlled syncing over a segment of * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is * zero then sys_sync_file_range() will operate from offset out to EOF. diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 5f3d725d112..3aa3434621c 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -103,7 +103,7 @@ static int init_dir(struct inode * inode) inode->i_fop = &sysfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); return 0; } @@ -137,7 +137,7 @@ static int create_dir(struct kobject * k, struct dentry * p, if (!error) { error = sysfs_create(*d, mode, init_dir); if (!error) { - p->d_inode->i_nlink++; + inc_nlink(p->d_inode); (*d)->d_op = &sysfs_dentry_ops; d_rehash(*d); } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index cf3786625bf..146f1dedec8 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -157,8 +157,8 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) if ((retval = fill_read_buffer(file->f_dentry,buffer))) goto out; } - pr_debug("%s: count = %d, ppos = %lld, buf = %s\n", - __FUNCTION__,count,*ppos,buffer->page); + pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", + __FUNCTION__, count, *ppos, buffer->page); retval = flush_read_buffer(buffer,buf,count,ppos); out: up(&buffer->sem); diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 40190c48927..20551a1b8a5 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c @@ -49,7 +49,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_op = &sysfs_dir_inode_operations; inode->i_fop = &sysfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); } else { pr_debug("sysfs: could not get root inode\n"); return -ENOMEM; diff --git a/fs/sysv/file.c b/fs/sysv/file.c index a59e303135f..47a4b728f15 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c @@ -21,8 +21,10 @@ */ const struct file_operations sysv_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = sysv_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index b8a73f716fb..f7c08db8e34 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -250,7 +250,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, sysv_set_link(new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/udf/file.c b/fs/udf/file.c index a59e5f33daf..7aedd552cba 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -103,19 +103,21 @@ const struct address_space_operations udf_adinicb_aops = { .commit_write = udf_adinicb_commit_write, }; -static ssize_t udf_file_write(struct file * file, const char __user * buf, - size_t count, loff_t *ppos) +static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t ppos) { ssize_t retval; + struct file *file = iocb->ki_filp; struct inode *inode = file->f_dentry->d_inode; int err, pos; + size_t count = iocb->ki_left; if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) { if (file->f_flags & O_APPEND) pos = inode->i_size; else - pos = *ppos; + pos = ppos; if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + pos + count)) @@ -136,7 +138,7 @@ static ssize_t udf_file_write(struct file * file, const char __user * buf, } } - retval = generic_file_write(file, buf, count, ppos); + retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); if (retval > 0) mark_inode_dirty(inode); @@ -249,11 +251,13 @@ static int udf_release_file(struct inode * inode, struct file * filp) } const struct file_operations udf_file_operations = { - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .ioctl = udf_ioctl, .open = generic_file_open, .mmap = generic_file_mmap, - .write = udf_file_write, + .write = do_sync_write, + .aio_write = udf_file_aio_write, .release = udf_release_file, .fsync = udf_fsync_file, .sendfile = generic_file_sendfile, diff --git a/fs/udf/inode.c b/fs/udf/inode.c index b223b32db99..ae21a0e59e9 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1165,7 +1165,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) inode->i_op = &udf_dir_inode_operations; inode->i_fop = &udf_dir_operations; inode->i_mode |= S_IFDIR; - inode->i_nlink ++; + inc_nlink(inode); break; } case ICBTAG_FILE_TYPE_REALTIME: diff --git a/fs/udf/namei.c b/fs/udf/namei.c index ab9a7629d23..73163325e5e 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -762,7 +762,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); - dir->i_nlink++; + inc_nlink(dir); mark_inode_dirty(dir); d_instantiate(dentry, inode); if (fibh.sbh != fibh.ebh) @@ -876,10 +876,9 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) udf_warning(inode->i_sb, "udf_rmdir", "empty directory has nlink != 2 (%d)", inode->i_nlink); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_size = 0; - mark_inode_dirty(inode); - dir->i_nlink --; + inode_dec_link_count(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); mark_inode_dirty(dir); @@ -923,8 +922,7 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) goto end_unlink; dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); mark_inode_dirty(dir); - inode->i_nlink--; - mark_inode_dirty(inode); + inode_dec_link_count(inode); inode->i_ctime = dir->i_ctime; retval = 0; @@ -1101,8 +1099,7 @@ out: return err; out_no_entry: - inode->i_nlink--; - mark_inode_dirty(inode); + inode_dec_link_count(inode); iput(inode); goto out; } @@ -1150,7 +1147,7 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir, if (fibh.sbh != fibh.ebh) udf_release_data(fibh.ebh); udf_release_data(fibh.sbh); - inode->i_nlink ++; + inc_nlink(inode); inode->i_ctime = current_fs_time(inode->i_sb); mark_inode_dirty(inode); atomic_inc(&inode->i_count); @@ -1261,9 +1258,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, if (new_inode) { - new_inode->i_nlink--; new_inode->i_ctime = current_fs_time(new_inode->i_sb); - mark_inode_dirty(new_inode); + inode_dec_link_count(new_inode); } old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); mark_inode_dirty(old_dir); @@ -1279,16 +1275,14 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, } else mark_buffer_dirty_inode(dir_bh, old_inode); - old_dir->i_nlink --; - mark_inode_dirty(old_dir); + inode_dec_link_count(old_dir); if (new_inode) { - new_inode->i_nlink --; - mark_inode_dirty(new_inode); + inode_dec_link_count(new_inode); } else { - new_dir->i_nlink ++; + inc_nlink(new_dir); mark_inode_dirty(new_dir); } } diff --git a/fs/ufs/file.c b/fs/ufs/file.c index a9c6e5f04fa..1e096323bad 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -53,8 +53,10 @@ static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync) const struct file_operations ufs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .open = generic_file_open, .fsync = ufs_sync_file, diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index d344b411e26..e84c0ecf073 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -308,7 +308,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, ufs_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/utimes.c b/fs/utimes.c new file mode 100644 index 00000000000..1bcd852fc4a --- /dev/null +++ b/fs/utimes.c @@ -0,0 +1,137 @@ +#include <linux/compiler.h> +#include <linux/fs.h> +#include <linux/linkage.h> +#include <linux/namei.h> +#include <linux/utime.h> +#include <asm/uaccess.h> +#include <asm/unistd.h> + +#ifdef __ARCH_WANT_SYS_UTIME + +/* + * sys_utime() can be implemented in user-level using sys_utimes(). + * Is this for backwards compatibility? If so, why not move it + * into the appropriate arch directory (for those architectures that + * need it). + */ + +/* If times==NULL, set access and modification to current time, + * must be owner or have write permission. + * Else, update from *times, must be owner or super user. + */ +asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) +{ + int error; + struct nameidata nd; + struct inode * inode; + struct iattr newattrs; + + error = user_path_walk(filename, &nd); + if (error) + goto out; + inode = nd.dentry->d_inode; + + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; + + /* Don't worry, the checks are done in inode_change_ok() */ + newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; + if (times) { + error = -EPERM; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + goto dput_and_out; + + error = get_user(newattrs.ia_atime.tv_sec, ×->actime); + newattrs.ia_atime.tv_nsec = 0; + if (!error) + error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); + newattrs.ia_mtime.tv_nsec = 0; + if (error) + goto dput_and_out; + + newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; + } else { + error = -EACCES; + if (IS_IMMUTABLE(inode)) + goto dput_and_out; + + if (current->fsuid != inode->i_uid && + (error = vfs_permission(&nd, MAY_WRITE)) != 0) + goto dput_and_out; + } + mutex_lock(&inode->i_mutex); + error = notify_change(nd.dentry, &newattrs); + mutex_unlock(&inode->i_mutex); +dput_and_out: + path_release(&nd); +out: + return error; +} + +#endif + +/* If times==NULL, set access and modification to current time, + * must be owner or have write permission. + * Else, update from *times, must be owner or super user. + */ +long do_utimes(int dfd, char __user *filename, struct timeval *times) +{ + int error; + struct nameidata nd; + struct inode * inode; + struct iattr newattrs; + + error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); + + if (error) + goto out; + inode = nd.dentry->d_inode; + + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; + + /* Don't worry, the checks are done in inode_change_ok() */ + newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; + if (times) { + error = -EPERM; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + goto dput_and_out; + + newattrs.ia_atime.tv_sec = times[0].tv_sec; + newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000; + newattrs.ia_mtime.tv_sec = times[1].tv_sec; + newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000; + newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; + } else { + error = -EACCES; + if (IS_IMMUTABLE(inode)) + goto dput_and_out; + + if (current->fsuid != inode->i_uid && + (error = vfs_permission(&nd, MAY_WRITE)) != 0) + goto dput_and_out; + } + mutex_lock(&inode->i_mutex); + error = notify_change(nd.dentry, &newattrs); + mutex_unlock(&inode->i_mutex); +dput_and_out: + path_release(&nd); +out: + return error; +} + +asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) +{ + struct timeval times[2]; + + if (utimes && copy_from_user(×, utimes, sizeof(times))) + return -EFAULT; + return do_utimes(dfd, filename, utimes ? times : NULL); +} + +asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) +{ + return sys_futimesat(AT_FDCWD, filename, utimes); +} diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 9a8f48bae95..edb711ff7b0 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -782,9 +782,9 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - dir->i_nlink--; + drop_nlink(dir); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; fat_detach(inode); out: @@ -808,7 +808,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; fat_detach(inode); out: @@ -837,7 +837,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (err) goto out_free; dir->i_version++; - dir->i_nlink++; + inc_nlink(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); @@ -930,9 +930,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, if (err) goto error_dotdot; } - old_dir->i_nlink--; + drop_nlink(old_dir); if (!new_inode) - new_dir->i_nlink++; + inc_nlink(new_dir); } err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */ @@ -947,10 +947,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, mark_inode_dirty(old_dir); if (new_inode) { + drop_nlink(new_inode); if (is_dir) - new_inode->i_nlink -= 2; - else - new_inode->i_nlink--; + drop_nlink(new_inode); new_inode->i_ctime = ts; } out: diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 26b364c9d62..35115bca036 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -1,5 +1,6 @@ config XFS_FS tristate "XFS filesystem support" + depends on BLOCK help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 41cfcba7ce4..d93d8dd1958 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -49,50 +49,49 @@ static struct vm_operations_struct xfs_dmapi_file_vm_ops; STATIC inline ssize_t __xfs_file_read( struct kiocb *iocb, - char __user *buf, + const struct iovec *iov, + unsigned long nr_segs, int ioflags, - size_t count, loff_t pos) { - struct iovec iov = {buf, count}; struct file *file = iocb->ki_filp; bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); BUG_ON(iocb->ki_pos != pos); if (unlikely(file->f_flags & O_DIRECT)) ioflags |= IO_ISDIRECT; - return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); + return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos, + ioflags, NULL); } STATIC ssize_t xfs_file_aio_read( struct kiocb *iocb, - char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos); + return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos); } STATIC ssize_t xfs_file_aio_read_invis( struct kiocb *iocb, - char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); + return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); } STATIC inline ssize_t __xfs_file_write( - struct kiocb *iocb, - const char __user *buf, - int ioflags, - size_t count, - loff_t pos) + struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, + int ioflags, + loff_t pos) { - struct iovec iov = {(void __user *)buf, count}; struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; bhv_vnode_t *vp = vn_from_inode(inode); @@ -100,117 +99,28 @@ __xfs_file_write( BUG_ON(iocb->ki_pos != pos); if (unlikely(file->f_flags & O_DIRECT)) ioflags |= IO_ISDIRECT; - return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); + return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos, + ioflags, NULL); } STATIC ssize_t xfs_file_aio_write( struct kiocb *iocb, - const char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos); + return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos); } STATIC ssize_t xfs_file_aio_write_invis( struct kiocb *iocb, - const char __user *buf, - size_t count, - loff_t pos) -{ - return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); -} - -STATIC inline ssize_t -__xfs_file_readv( - struct file *file, - const struct iovec *iov, - int ioflags, - unsigned long nr_segs, - loff_t *ppos) -{ - struct inode *inode = file->f_mapping->host; - bhv_vnode_t *vp = vn_from_inode(inode); - struct kiocb kiocb; - ssize_t rval; - - init_sync_kiocb(&kiocb, file); - kiocb.ki_pos = *ppos; - - if (unlikely(file->f_flags & O_DIRECT)) - ioflags |= IO_ISDIRECT; - rval = bhv_vop_read(vp, &kiocb, iov, nr_segs, - &kiocb.ki_pos, ioflags, NULL); - - *ppos = kiocb.ki_pos; - return rval; -} - -STATIC ssize_t -xfs_file_readv( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_readv(file, iov, 0, nr_segs, ppos); -} - -STATIC ssize_t -xfs_file_readv_invis( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); -} - -STATIC inline ssize_t -__xfs_file_writev( - struct file *file, - const struct iovec *iov, - int ioflags, - unsigned long nr_segs, - loff_t *ppos) -{ - struct inode *inode = file->f_mapping->host; - bhv_vnode_t *vp = vn_from_inode(inode); - struct kiocb kiocb; - ssize_t rval; - - init_sync_kiocb(&kiocb, file); - kiocb.ki_pos = *ppos; - if (unlikely(file->f_flags & O_DIRECT)) - ioflags |= IO_ISDIRECT; - - rval = bhv_vop_write(vp, &kiocb, iov, nr_segs, - &kiocb.ki_pos, ioflags, NULL); - - *ppos = kiocb.ki_pos; - return rval; -} - -STATIC ssize_t -xfs_file_writev( - struct file *file, - const struct iovec *iov, + const struct iovec *iov, unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_writev(file, iov, 0, nr_segs, ppos); -} - -STATIC ssize_t -xfs_file_writev_invis( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) + loff_t pos) { - return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos); + return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); } STATIC ssize_t @@ -540,8 +450,6 @@ const struct file_operations xfs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, - .readv = xfs_file_readv, - .writev = xfs_file_writev, .aio_read = xfs_file_aio_read, .aio_write = xfs_file_aio_write, .sendfile = xfs_file_sendfile, @@ -565,8 +473,6 @@ const struct file_operations xfs_invis_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, - .readv = xfs_file_readv_invis, - .writev = xfs_file_writev_invis, .aio_read = xfs_file_aio_read_invis, .aio_write = xfs_file_aio_write_invis, .sendfile = xfs_file_sendfile_invis, diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 55992b40353..fa842f1c9fa 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -279,7 +279,9 @@ xfs_read( xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, (void *)iovp, segs, *offset, ioflags); - ret = __generic_file_aio_read(iocb, iovp, segs, offset); + + iocb->ki_pos = *offset; + ret = generic_file_aio_read(iocb, iovp, segs, *offset); if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) ret = wait_on_sync_kiocb(iocb); if (ret > 0) |