#include "dat.h"
-#define KMALLOC_SIZE_MIN 4096 /* 4KB */
-#define KMALLOC_SIZE_MAX 131072 /* 128 KB */
-
static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
struct nilfs_argv *argv, int dir,
ssize_t (*dofunc)(struct the_nilfs *,
void *, size_t, size_t))
{
void *buf;
- size_t ksize, maxmembs, total, n;
+ size_t maxmembs, total, n;
ssize_t nr;
int ret, i;
if (argv->v_nmembs == 0)
return 0;
- for (ksize = KMALLOC_SIZE_MAX; ksize >= KMALLOC_SIZE_MIN; ksize /= 2) {
- buf = kmalloc(ksize, GFP_NOFS);
- if (buf != NULL)
- break;
- }
- if (ksize < KMALLOC_SIZE_MIN)
+ if (argv->v_size > PAGE_SIZE)
+ return -EINVAL;
+
+ buf = (void *)__get_free_pages(GFP_NOFS, 0);
+ if (unlikely(!buf))
return -ENOMEM;
- maxmembs = ksize / argv->v_size;
+ maxmembs = PAGE_SIZE / argv->v_size;
ret = 0;
total = 0;
}
argv->v_nmembs = total;
- kfree(buf);
+ free_pages((unsigned long)buf, 0);
return ret;
}
nilfs_transaction_begin(inode->i_sb, &ti, 0);
ret = nilfs_cpfile_change_cpmode(
cpfile, cpmode.cm_cno, cpmode.cm_mode);
- nilfs_transaction_end(inode->i_sb, !ret);
+ if (unlikely(ret < 0)) {
+ nilfs_transaction_abort(inode->i_sb);
+ return ret;
+ }
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
return ret;
}
nilfs_transaction_begin(inode->i_sb, &ti, 0);
ret = nilfs_cpfile_delete_checkpoint(cpfile, cno);
- nilfs_transaction_end(inode->i_sb, !ret);
+ if (unlikely(ret < 0)) {
+ nilfs_transaction_abort(inode->i_sb);
+ return ret;
+ }
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
return ret;
}
{
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
struct nilfs_argv argv;
- struct nilfs_transaction_info ti;
int ret;
if (copy_from_user(&argv, argp, sizeof(argv)))
return -EFAULT;
- nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ down_read(&nilfs->ns_segctor_sem);
ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
nilfs_ioctl_do_get_cpinfo);
- nilfs_transaction_end(inode->i_sb, 0);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
if (copy_to_user(argp, &argv, sizeof(argv)))
ret = -EFAULT;
static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp)
{
- struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile;
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
struct nilfs_cpstat cpstat;
- struct nilfs_transaction_info ti;
int ret;
- nilfs_transaction_begin(inode->i_sb, &ti, 0);
- ret = nilfs_cpfile_get_stat(cpfile, &cpstat);
- nilfs_transaction_end(inode->i_sb, 0);
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
+ up_read(&nilfs->ns_segctor_sem);
if (ret < 0)
return ret;
{
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
struct nilfs_argv argv;
- struct nilfs_transaction_info ti;
int ret;
if (copy_from_user(&argv, argp, sizeof(argv)))
return -EFAULT;
- nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ down_read(&nilfs->ns_segctor_sem);
ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
nilfs_ioctl_do_get_suinfo);
- nilfs_transaction_end(inode->i_sb, 0);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
if (copy_to_user(argp, &argv, sizeof(argv)))
ret = -EFAULT;
static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp)
{
- struct inode *sufile = NILFS_SB(inode->i_sb)->s_nilfs->ns_sufile;
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
struct nilfs_sustat sustat;
- struct nilfs_transaction_info ti;
int ret;
- nilfs_transaction_begin(inode->i_sb, &ti, 0);
- ret = nilfs_sufile_get_stat(sufile, &sustat);
- nilfs_transaction_end(inode->i_sb, 0);
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
+ up_read(&nilfs->ns_segctor_sem);
if (ret < 0)
return ret;
{
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
struct nilfs_argv argv;
- struct nilfs_transaction_info ti;
int ret;
if (copy_from_user(&argv, argp, sizeof(argv)))
return -EFAULT;
- nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ down_read(&nilfs->ns_segctor_sem);
ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
nilfs_ioctl_do_get_vinfo);
- nilfs_transaction_end(inode->i_sb, 0);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
if (copy_to_user(argp, &argv, sizeof(argv)))
ret = -EFAULT;
{
struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
struct nilfs_argv argv;
- struct nilfs_transaction_info ti;
int ret;
if (copy_from_user(&argv, argp, sizeof(argv)))
return -EFAULT;
- nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ down_read(&nilfs->ns_segctor_sem);
ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
nilfs_ioctl_do_get_bdescs);
- nilfs_transaction_end(inode->i_sb, 0);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
if (copy_to_user(argp, &argv, sizeof(argv)))
ret = -EFAULT;