~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nilfs2/ioctl.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/nilfs2/ioctl.c (Version linux-6.12-rc7) and /fs/nilfs2/ioctl.c (Version linux-4.4.302)


  1 // SPDX-License-Identifier: GPL-2.0+           << 
  2 /*                                                  1 /*
  3  * NILFS ioctl operations.                     !!   2  * ioctl.c - NILFS ioctl operations.
  4  *                                                  3  *
  5  * Copyright (C) 2007, 2008 Nippon Telegraph a      4  * Copyright (C) 2007, 2008 Nippon Telegraph and Telephone Corporation.
  6  *                                                  5  *
  7  * Written by Koji Sato.                       !!   6  * This program is free software; you can redistribute it and/or modify
                                                   >>   7  * it under the terms of the GNU General Public License as published by
                                                   >>   8  * the Free Software Foundation; either version 2 of the License, or
                                                   >>   9  * (at your option) any later version.
                                                   >>  10  *
                                                   >>  11  * This program is distributed in the hope that it will be useful,
                                                   >>  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                                                   >>  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                                                   >>  14  * GNU General Public License for more details.
                                                   >>  15  *
                                                   >>  16  * You should have received a copy of the GNU General Public License
                                                   >>  17  * along with this program; if not, write to the Free Software
                                                   >>  18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
                                                   >>  19  *
                                                   >>  20  * Written by Koji Sato <koji@osrg.net>.
  8  */                                                21  */
  9                                                    22 
 10 #include <linux/fs.h>                              23 #include <linux/fs.h>
 11 #include <linux/wait.h>                            24 #include <linux/wait.h>
 12 #include <linux/slab.h>                            25 #include <linux/slab.h>
 13 #include <linux/capability.h>   /* capable() *     26 #include <linux/capability.h>   /* capable() */
 14 #include <linux/uaccess.h>      /* copy_from_u     27 #include <linux/uaccess.h>      /* copy_from_user(), copy_to_user() */
 15 #include <linux/vmalloc.h>                         28 #include <linux/vmalloc.h>
 16 #include <linux/compat.h>       /* compat_ptr(     29 #include <linux/compat.h>       /* compat_ptr() */
 17 #include <linux/mount.h>        /* mnt_want_wr     30 #include <linux/mount.h>        /* mnt_want_write_file(), mnt_drop_write_file() */
 18 #include <linux/buffer_head.h>                     31 #include <linux/buffer_head.h>
 19 #include <linux/fileattr.h>                    !!  32 #include <linux/nilfs2_fs.h>
 20 #include <linux/string.h>                      << 
 21 #include "nilfs.h"                                 33 #include "nilfs.h"
 22 #include "segment.h"                               34 #include "segment.h"
 23 #include "bmap.h"                                  35 #include "bmap.h"
 24 #include "cpfile.h"                                36 #include "cpfile.h"
 25 #include "sufile.h"                                37 #include "sufile.h"
 26 #include "dat.h"                                   38 #include "dat.h"
 27                                                    39 
 28 /**                                                40 /**
 29  * nilfs_ioctl_wrap_copy - wrapping function o     41  * nilfs_ioctl_wrap_copy - wrapping function of get/set metadata info
 30  * @nilfs: nilfs object                            42  * @nilfs: nilfs object
 31  * @argv: vector of arguments from userspace       43  * @argv: vector of arguments from userspace
 32  * @dir: set of direction flags                    44  * @dir: set of direction flags
 33  * @dofunc: concrete function of get/set metad     45  * @dofunc: concrete function of get/set metadata info
 34  *                                                 46  *
 35  * Description: nilfs_ioctl_wrap_copy() gets/s     47  * Description: nilfs_ioctl_wrap_copy() gets/sets metadata info by means of
 36  * calling dofunc() function on the basis of @     48  * calling dofunc() function on the basis of @argv argument.
 37  *                                                 49  *
 38  * Return Value: On success, 0 is returned and     50  * Return Value: On success, 0 is returned and requested metadata info
 39  * is copied into userspace. On error, one of      51  * is copied into userspace. On error, one of the following
 40  * negative error codes is returned.               52  * negative error codes is returned.
 41  *                                                 53  *
 42  * %-EINVAL - Invalid arguments from userspace     54  * %-EINVAL - Invalid arguments from userspace.
 43  *                                                 55  *
 44  * %-ENOMEM - Insufficient amount of memory av     56  * %-ENOMEM - Insufficient amount of memory available.
 45  *                                                 57  *
 46  * %-EFAULT - Failure during execution of requ     58  * %-EFAULT - Failure during execution of requested operation.
 47  */                                                59  */
 48 static int nilfs_ioctl_wrap_copy(struct the_ni     60 static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
 49                                  struct nilfs_     61                                  struct nilfs_argv *argv, int dir,
 50                                  ssize_t (*dof     62                                  ssize_t (*dofunc)(struct the_nilfs *,
 51                                                    63                                                    __u64 *, int,
 52                                                    64                                                    void *, size_t, size_t))
 53 {                                                  65 {
 54         void *buf;                                 66         void *buf;
 55         void __user *base = (void __user *)(un     67         void __user *base = (void __user *)(unsigned long)argv->v_base;
 56         size_t maxmembs, total, n;                 68         size_t maxmembs, total, n;
 57         ssize_t nr;                                69         ssize_t nr;
 58         int ret, i;                                70         int ret, i;
 59         __u64 pos, ppos;                           71         __u64 pos, ppos;
 60                                                    72 
 61         if (argv->v_nmembs == 0)                   73         if (argv->v_nmembs == 0)
 62                 return 0;                          74                 return 0;
 63                                                    75 
 64         if ((size_t)argv->v_size > PAGE_SIZE)  !!  76         if (argv->v_size > PAGE_SIZE)
 65                 return -EINVAL;                    77                 return -EINVAL;
 66                                                    78 
 67         /*                                         79         /*
 68          * Reject pairs of a start item positi     80          * Reject pairs of a start item position (argv->v_index) and a
 69          * total count (argv->v_nmembs) which      81          * total count (argv->v_nmembs) which leads position 'pos' to
 70          * overflow by the increment at the en     82          * overflow by the increment at the end of the loop.
 71          */                                        83          */
 72         if (argv->v_index > ~(__u64)0 - argv->     84         if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
 73                 return -EINVAL;                    85                 return -EINVAL;
 74                                                    86 
 75         buf = (void *)get_zeroed_page(GFP_NOFS !!  87         buf = (void *)__get_free_pages(GFP_NOFS, 0);
 76         if (unlikely(!buf))                        88         if (unlikely(!buf))
 77                 return -ENOMEM;                    89                 return -ENOMEM;
 78         maxmembs = PAGE_SIZE / argv->v_size;       90         maxmembs = PAGE_SIZE / argv->v_size;
 79                                                    91 
 80         ret = 0;                                   92         ret = 0;
 81         total = 0;                                 93         total = 0;
 82         pos = argv->v_index;                       94         pos = argv->v_index;
 83         for (i = 0; i < argv->v_nmembs; i += n     95         for (i = 0; i < argv->v_nmembs; i += n) {
 84                 n = (argv->v_nmembs - i < maxm     96                 n = (argv->v_nmembs - i < maxmembs) ?
 85                         argv->v_nmembs - i : m     97                         argv->v_nmembs - i : maxmembs;
 86                 if ((dir & _IOC_WRITE) &&          98                 if ((dir & _IOC_WRITE) &&
 87                     copy_from_user(buf, base +     99                     copy_from_user(buf, base + argv->v_size * i,
 88                                    argv->v_siz    100                                    argv->v_size * n)) {
 89                         ret = -EFAULT;            101                         ret = -EFAULT;
 90                         break;                    102                         break;
 91                 }                                 103                 }
 92                 ppos = pos;                       104                 ppos = pos;
 93                 nr = dofunc(nilfs, &pos, argv-    105                 nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size,
 94                                n);                106                                n);
 95                 if (nr < 0) {                     107                 if (nr < 0) {
 96                         ret = nr;                 108                         ret = nr;
 97                         break;                    109                         break;
 98                 }                                 110                 }
 99                 if ((dir & _IOC_READ) &&          111                 if ((dir & _IOC_READ) &&
100                     copy_to_user(base + argv->    112                     copy_to_user(base + argv->v_size * i, buf,
101                                  argv->v_size     113                                  argv->v_size * nr)) {
102                         ret = -EFAULT;            114                         ret = -EFAULT;
103                         break;                    115                         break;
104                 }                                 116                 }
105                 total += nr;                      117                 total += nr;
106                 if ((size_t)nr < n)               118                 if ((size_t)nr < n)
107                         break;                    119                         break;
108                 if (pos == ppos)                  120                 if (pos == ppos)
109                         pos += n;                 121                         pos += n;
110         }                                         122         }
111         argv->v_nmembs = total;                   123         argv->v_nmembs = total;
112                                                   124 
113         free_pages((unsigned long)buf, 0);        125         free_pages((unsigned long)buf, 0);
114         return ret;                               126         return ret;
115 }                                                 127 }
116                                                   128 
117 /**                                               129 /**
118  * nilfs_fileattr_get - retrieve miscellaneous !! 130  * nilfs_ioctl_getflags - ioctl to support lsattr
119  * @dentry: the object to retrieve from        << 
120  * @fa:     fileattr pointer                   << 
121  *                                             << 
122  * Return: always 0 as success.                << 
123  */                                               131  */
124 int nilfs_fileattr_get(struct dentry *dentry,  !! 132 static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp)
125 {                                                 133 {
126         struct inode *inode = d_inode(dentry); !! 134         unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE;
127                                                << 
128         fileattr_fill_flags(fa, NILFS_I(inode) << 
129                                                   135 
130         return 0;                              !! 136         return put_user(flags, (int __user *)argp);
131 }                                                 137 }
132                                                   138 
133 /**                                               139 /**
134  * nilfs_fileattr_set - change miscellaneous f !! 140  * nilfs_ioctl_setflags - ioctl to support chattr
135  * @idmap:  idmap of the mount                 << 
136  * @dentry: the object to change               << 
137  * @fa:     fileattr pointer                   << 
138  *                                             << 
139  * Return: 0 on success, or a negative error c << 
140  */                                               141  */
141 int nilfs_fileattr_set(struct mnt_idmap *idmap !! 142 static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
142                        struct dentry *dentry,  !! 143                                 void __user *argp)
143 {                                                 144 {
144         struct inode *inode = d_inode(dentry); << 
145         struct nilfs_transaction_info ti;         145         struct nilfs_transaction_info ti;
146         unsigned int flags, oldflags;             146         unsigned int flags, oldflags;
147         int ret;                                  147         int ret;
148                                                   148 
149         if (fileattr_has_fsx(fa))              !! 149         if (!inode_owner_or_capable(inode))
150                 return -EOPNOTSUPP;            !! 150                 return -EACCES;
151                                                   151 
152         flags = nilfs_mask_flags(inode->i_mode !! 152         if (get_user(flags, (int __user *)argp))
                                                   >> 153                 return -EFAULT;
153                                                   154 
154         ret = nilfs_transaction_begin(inode->i !! 155         ret = mnt_want_write_file(filp);
155         if (ret)                                  156         if (ret)
156                 return ret;                       157                 return ret;
157                                                   158 
158         oldflags = NILFS_I(inode)->i_flags & ~ !! 159         flags = nilfs_mask_flags(inode->i_mode, flags);
159         NILFS_I(inode)->i_flags = oldflags | ( !! 160 
                                                   >> 161         mutex_lock(&inode->i_mutex);
                                                   >> 162 
                                                   >> 163         oldflags = NILFS_I(inode)->i_flags;
                                                   >> 164 
                                                   >> 165         /*
                                                   >> 166          * The IMMUTABLE and APPEND_ONLY flags can only be changed by the
                                                   >> 167          * relevant capability.
                                                   >> 168          */
                                                   >> 169         ret = -EPERM;
                                                   >> 170         if (((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) &&
                                                   >> 171             !capable(CAP_LINUX_IMMUTABLE))
                                                   >> 172                 goto out;
                                                   >> 173 
                                                   >> 174         ret = nilfs_transaction_begin(inode->i_sb, &ti, 0);
                                                   >> 175         if (ret)
                                                   >> 176                 goto out;
                                                   >> 177 
                                                   >> 178         NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) |
                                                   >> 179                 (flags & FS_FL_USER_MODIFIABLE);
160                                                   180 
161         nilfs_set_inode_flags(inode);             181         nilfs_set_inode_flags(inode);
162         inode_set_ctime_current(inode);        !! 182         inode->i_ctime = CURRENT_TIME;
163         if (IS_SYNC(inode))                       183         if (IS_SYNC(inode))
164                 nilfs_set_transaction_flag(NIL    184                 nilfs_set_transaction_flag(NILFS_TI_SYNC);
165                                                   185 
166         nilfs_mark_inode_dirty(inode);            186         nilfs_mark_inode_dirty(inode);
167         return nilfs_transaction_commit(inode- !! 187         ret = nilfs_transaction_commit(inode->i_sb);
                                                   >> 188 out:
                                                   >> 189         mutex_unlock(&inode->i_mutex);
                                                   >> 190         mnt_drop_write_file(filp);
                                                   >> 191         return ret;
168 }                                                 192 }
169                                                   193 
170 /**                                               194 /**
171  * nilfs_ioctl_getversion - get info about a f    195  * nilfs_ioctl_getversion - get info about a file's version (generation number)
172  * @inode: inode object                        << 
173  * @argp:  userspace memory where the generati << 
174  *                                             << 
175  * Return: 0 on success, or %-EFAULT on error. << 
176  */                                               196  */
177 static int nilfs_ioctl_getversion(struct inode    197 static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp)
178 {                                                 198 {
179         return put_user(inode->i_generation, (    199         return put_user(inode->i_generation, (int __user *)argp);
180 }                                                 200 }
181                                                   201 
182 /**                                               202 /**
183  * nilfs_ioctl_change_cpmode - change checkpoi    203  * nilfs_ioctl_change_cpmode - change checkpoint mode (checkpoint/snapshot)
184  * @inode: inode object                           204  * @inode: inode object
185  * @filp: file object                             205  * @filp: file object
186  * @cmd: ioctl's request code                     206  * @cmd: ioctl's request code
187  * @argp: pointer on argument from userspace      207  * @argp: pointer on argument from userspace
188  *                                                208  *
189  * Description: nilfs_ioctl_change_cpmode() fu    209  * Description: nilfs_ioctl_change_cpmode() function changes mode of
190  * given checkpoint between checkpoint and sna    210  * given checkpoint between checkpoint and snapshot state. This ioctl
191  * is used in chcp and mkcp utilities.            211  * is used in chcp and mkcp utilities.
192  *                                                212  *
193  * Return Value: On success, 0 is returned and    213  * Return Value: On success, 0 is returned and mode of a checkpoint is
194  * changed. On error, one of the following neg    214  * changed. On error, one of the following negative error codes
195  * is returned.                                   215  * is returned.
196  *                                                216  *
197  * %-EPERM - Operation not permitted.             217  * %-EPERM - Operation not permitted.
198  *                                                218  *
199  * %-EFAULT - Failure during checkpoint mode c    219  * %-EFAULT - Failure during checkpoint mode changing.
200  */                                               220  */
201 static int nilfs_ioctl_change_cpmode(struct in    221 static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
202                                      unsigned     222                                      unsigned int cmd, void __user *argp)
203 {                                                 223 {
204         struct the_nilfs *nilfs = inode->i_sb-    224         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
205         struct nilfs_transaction_info ti;         225         struct nilfs_transaction_info ti;
206         struct nilfs_cpmode cpmode;               226         struct nilfs_cpmode cpmode;
207         int ret;                                  227         int ret;
208                                                   228 
209         if (!capable(CAP_SYS_ADMIN))              229         if (!capable(CAP_SYS_ADMIN))
210                 return -EPERM;                    230                 return -EPERM;
211                                                   231 
212         ret = mnt_want_write_file(filp);          232         ret = mnt_want_write_file(filp);
213         if (ret)                                  233         if (ret)
214                 return ret;                       234                 return ret;
215                                                   235 
216         ret = -EFAULT;                            236         ret = -EFAULT;
217         if (copy_from_user(&cpmode, argp, size    237         if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
218                 goto out;                         238                 goto out;
219                                                   239 
220         mutex_lock(&nilfs->ns_snapshot_mount_m    240         mutex_lock(&nilfs->ns_snapshot_mount_mutex);
221                                                   241 
222         nilfs_transaction_begin(inode->i_sb, &    242         nilfs_transaction_begin(inode->i_sb, &ti, 0);
223         ret = nilfs_cpfile_change_cpmode(         243         ret = nilfs_cpfile_change_cpmode(
224                 nilfs->ns_cpfile, cpmode.cm_cn    244                 nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode);
225         if (unlikely(ret < 0))                    245         if (unlikely(ret < 0))
226                 nilfs_transaction_abort(inode-    246                 nilfs_transaction_abort(inode->i_sb);
227         else                                      247         else
228                 nilfs_transaction_commit(inode    248                 nilfs_transaction_commit(inode->i_sb); /* never fails */
229                                                   249 
230         mutex_unlock(&nilfs->ns_snapshot_mount    250         mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
231 out:                                              251 out:
232         mnt_drop_write_file(filp);                252         mnt_drop_write_file(filp);
233         return ret;                               253         return ret;
234 }                                                 254 }
235                                                   255 
236 /**                                               256 /**
237  * nilfs_ioctl_delete_checkpoint - remove chec    257  * nilfs_ioctl_delete_checkpoint - remove checkpoint
238  * @inode: inode object                           258  * @inode: inode object
239  * @filp: file object                             259  * @filp: file object
240  * @cmd: ioctl's request code                     260  * @cmd: ioctl's request code
241  * @argp: pointer on argument from userspace      261  * @argp: pointer on argument from userspace
242  *                                                262  *
243  * Description: nilfs_ioctl_delete_checkpoint(    263  * Description: nilfs_ioctl_delete_checkpoint() function removes
244  * checkpoint from NILFS2 file system. This io    264  * checkpoint from NILFS2 file system. This ioctl is used in rmcp
245  * utility.                                       265  * utility.
246  *                                                266  *
247  * Return Value: On success, 0 is returned and    267  * Return Value: On success, 0 is returned and a checkpoint is
248  * removed. On error, one of the following neg    268  * removed. On error, one of the following negative error codes
249  * is returned.                                   269  * is returned.
250  *                                                270  *
251  * %-EPERM - Operation not permitted.             271  * %-EPERM - Operation not permitted.
252  *                                                272  *
253  * %-EFAULT - Failure during checkpoint removi    273  * %-EFAULT - Failure during checkpoint removing.
254  */                                               274  */
255 static int                                        275 static int
256 nilfs_ioctl_delete_checkpoint(struct inode *in    276 nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
257                               unsigned int cmd    277                               unsigned int cmd, void __user *argp)
258 {                                                 278 {
259         struct the_nilfs *nilfs = inode->i_sb-    279         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
260         struct nilfs_transaction_info ti;         280         struct nilfs_transaction_info ti;
261         __u64 cno;                                281         __u64 cno;
262         int ret;                                  282         int ret;
263                                                   283 
264         if (!capable(CAP_SYS_ADMIN))              284         if (!capable(CAP_SYS_ADMIN))
265                 return -EPERM;                    285                 return -EPERM;
266                                                   286 
267         ret = mnt_want_write_file(filp);          287         ret = mnt_want_write_file(filp);
268         if (ret)                                  288         if (ret)
269                 return ret;                       289                 return ret;
270                                                   290 
271         ret = -EFAULT;                            291         ret = -EFAULT;
272         if (copy_from_user(&cno, argp, sizeof(    292         if (copy_from_user(&cno, argp, sizeof(cno)))
273                 goto out;                         293                 goto out;
274                                                   294 
275         nilfs_transaction_begin(inode->i_sb, &    295         nilfs_transaction_begin(inode->i_sb, &ti, 0);
276         ret = nilfs_cpfile_delete_checkpoint(n    296         ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno);
277         if (unlikely(ret < 0))                    297         if (unlikely(ret < 0))
278                 nilfs_transaction_abort(inode-    298                 nilfs_transaction_abort(inode->i_sb);
279         else                                      299         else
280                 nilfs_transaction_commit(inode    300                 nilfs_transaction_commit(inode->i_sb); /* never fails */
281 out:                                              301 out:
282         mnt_drop_write_file(filp);                302         mnt_drop_write_file(filp);
283         return ret;                               303         return ret;
284 }                                                 304 }
285                                                   305 
286 /**                                               306 /**
287  * nilfs_ioctl_do_get_cpinfo - callback method    307  * nilfs_ioctl_do_get_cpinfo - callback method getting info about checkpoints
288  * @nilfs: nilfs object                           308  * @nilfs: nilfs object
289  * @posp: pointer on array of checkpoint's num    309  * @posp: pointer on array of checkpoint's numbers
290  * @flags: checkpoint mode (checkpoint or snap    310  * @flags: checkpoint mode (checkpoint or snapshot)
291  * @buf: buffer for storing checkponts' info      311  * @buf: buffer for storing checkponts' info
292  * @size: size in bytes of one checkpoint info    312  * @size: size in bytes of one checkpoint info item in array
293  * @nmembs: number of checkpoints in array (nu    313  * @nmembs: number of checkpoints in array (numbers and infos)
294  *                                                314  *
295  * Description: nilfs_ioctl_do_get_cpinfo() fu    315  * Description: nilfs_ioctl_do_get_cpinfo() function returns info about
296  * requested checkpoints. The NILFS_IOCTL_GET_    316  * requested checkpoints. The NILFS_IOCTL_GET_CPINFO ioctl is used in
297  * lscp utility and by nilfs_cleanerd daemon.     317  * lscp utility and by nilfs_cleanerd daemon.
298  *                                                318  *
299  * Return value: count of nilfs_cpinfo structu    319  * Return value: count of nilfs_cpinfo structures in output buffer.
300  */                                               320  */
301 static ssize_t                                    321 static ssize_t
302 nilfs_ioctl_do_get_cpinfo(struct the_nilfs *ni    322 nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
303                           void *buf, size_t si    323                           void *buf, size_t size, size_t nmembs)
304 {                                                 324 {
305         int ret;                                  325         int ret;
306                                                   326 
307         down_read(&nilfs->ns_segctor_sem);        327         down_read(&nilfs->ns_segctor_sem);
308         ret = nilfs_cpfile_get_cpinfo(nilfs->n    328         ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
309                                       size, nm    329                                       size, nmembs);
310         up_read(&nilfs->ns_segctor_sem);          330         up_read(&nilfs->ns_segctor_sem);
311         return ret;                               331         return ret;
312 }                                                 332 }
313                                                   333 
314 /**                                               334 /**
315  * nilfs_ioctl_get_cpstat - get checkpoints st    335  * nilfs_ioctl_get_cpstat - get checkpoints statistics
316  * @inode: inode object                           336  * @inode: inode object
317  * @filp: file object                             337  * @filp: file object
318  * @cmd: ioctl's request code                     338  * @cmd: ioctl's request code
319  * @argp: pointer on argument from userspace      339  * @argp: pointer on argument from userspace
320  *                                                340  *
321  * Description: nilfs_ioctl_get_cpstat() retur    341  * Description: nilfs_ioctl_get_cpstat() returns information about checkpoints.
322  * The NILFS_IOCTL_GET_CPSTAT ioctl is used by    342  * The NILFS_IOCTL_GET_CPSTAT ioctl is used by lscp, rmcp utilities
323  * and by nilfs_cleanerd daemon.                  343  * and by nilfs_cleanerd daemon.
324  *                                                344  *
325  * Return Value: On success, 0 is returned, an    345  * Return Value: On success, 0 is returned, and checkpoints information is
326  * copied into userspace pointer @argp. On err    346  * copied into userspace pointer @argp. On error, one of the following
327  * negative error codes is returned.              347  * negative error codes is returned.
328  *                                                348  *
329  * %-EIO - I/O error.                             349  * %-EIO - I/O error.
330  *                                                350  *
331  * %-ENOMEM - Insufficient amount of memory av    351  * %-ENOMEM - Insufficient amount of memory available.
332  *                                                352  *
333  * %-EFAULT - Failure during getting checkpoin    353  * %-EFAULT - Failure during getting checkpoints statistics.
334  */                                               354  */
335 static int nilfs_ioctl_get_cpstat(struct inode    355 static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
336                                   unsigned int    356                                   unsigned int cmd, void __user *argp)
337 {                                                 357 {
338         struct the_nilfs *nilfs = inode->i_sb-    358         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
339         struct nilfs_cpstat cpstat;               359         struct nilfs_cpstat cpstat;
340         int ret;                                  360         int ret;
341                                                   361 
342         down_read(&nilfs->ns_segctor_sem);        362         down_read(&nilfs->ns_segctor_sem);
343         ret = nilfs_cpfile_get_stat(nilfs->ns_    363         ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
344         up_read(&nilfs->ns_segctor_sem);          364         up_read(&nilfs->ns_segctor_sem);
345         if (ret < 0)                              365         if (ret < 0)
346                 return ret;                       366                 return ret;
347                                                   367 
348         if (copy_to_user(argp, &cpstat, sizeof    368         if (copy_to_user(argp, &cpstat, sizeof(cpstat)))
349                 ret = -EFAULT;                    369                 ret = -EFAULT;
350         return ret;                               370         return ret;
351 }                                                 371 }
352                                                   372 
353 /**                                               373 /**
354  * nilfs_ioctl_do_get_suinfo - callback method    374  * nilfs_ioctl_do_get_suinfo - callback method getting segment usage info
355  * @nilfs: nilfs object                           375  * @nilfs: nilfs object
356  * @posp: pointer on array of segment numbers     376  * @posp: pointer on array of segment numbers
357  * @flags: *not used*                             377  * @flags: *not used*
358  * @buf: buffer for storing suinfo array          378  * @buf: buffer for storing suinfo array
359  * @size: size in bytes of one suinfo item in     379  * @size: size in bytes of one suinfo item in array
360  * @nmembs: count of segment numbers and suinf    380  * @nmembs: count of segment numbers and suinfos in array
361  *                                                381  *
362  * Description: nilfs_ioctl_do_get_suinfo() fu    382  * Description: nilfs_ioctl_do_get_suinfo() function returns segment usage
363  * info about requested segments. The NILFS_IO    383  * info about requested segments. The NILFS_IOCTL_GET_SUINFO ioctl is used
364  * in lssu, nilfs_resize utilities and by nilf    384  * in lssu, nilfs_resize utilities and by nilfs_cleanerd daemon.
365  *                                                385  *
366  * Return value: count of nilfs_suinfo structu    386  * Return value: count of nilfs_suinfo structures in output buffer.
367  */                                               387  */
368 static ssize_t                                    388 static ssize_t
369 nilfs_ioctl_do_get_suinfo(struct the_nilfs *ni    389 nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
370                           void *buf, size_t si    390                           void *buf, size_t size, size_t nmembs)
371 {                                                 391 {
372         int ret;                                  392         int ret;
373                                                   393 
374         down_read(&nilfs->ns_segctor_sem);        394         down_read(&nilfs->ns_segctor_sem);
375         ret = nilfs_sufile_get_suinfo(nilfs->n    395         ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
376                                       nmembs);    396                                       nmembs);
377         up_read(&nilfs->ns_segctor_sem);          397         up_read(&nilfs->ns_segctor_sem);
378         return ret;                               398         return ret;
379 }                                                 399 }
380                                                   400 
381 /**                                               401 /**
382  * nilfs_ioctl_get_sustat - get segment usage     402  * nilfs_ioctl_get_sustat - get segment usage statistics
383  * @inode: inode object                           403  * @inode: inode object
384  * @filp: file object                             404  * @filp: file object
385  * @cmd: ioctl's request code                     405  * @cmd: ioctl's request code
386  * @argp: pointer on argument from userspace      406  * @argp: pointer on argument from userspace
387  *                                                407  *
388  * Description: nilfs_ioctl_get_sustat() retur    408  * Description: nilfs_ioctl_get_sustat() returns segment usage statistics.
389  * The NILFS_IOCTL_GET_SUSTAT ioctl is used in    409  * The NILFS_IOCTL_GET_SUSTAT ioctl is used in lssu, nilfs_resize utilities
390  * and by nilfs_cleanerd daemon.                  410  * and by nilfs_cleanerd daemon.
391  *                                                411  *
392  * Return Value: On success, 0 is returned, an    412  * Return Value: On success, 0 is returned, and segment usage information is
393  * copied into userspace pointer @argp. On err    413  * copied into userspace pointer @argp. On error, one of the following
394  * negative error codes is returned.              414  * negative error codes is returned.
395  *                                                415  *
396  * %-EIO - I/O error.                             416  * %-EIO - I/O error.
397  *                                                417  *
398  * %-ENOMEM - Insufficient amount of memory av    418  * %-ENOMEM - Insufficient amount of memory available.
399  *                                                419  *
400  * %-EFAULT - Failure during getting segment u    420  * %-EFAULT - Failure during getting segment usage statistics.
401  */                                               421  */
402 static int nilfs_ioctl_get_sustat(struct inode    422 static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
403                                   unsigned int    423                                   unsigned int cmd, void __user *argp)
404 {                                                 424 {
405         struct the_nilfs *nilfs = inode->i_sb-    425         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
406         struct nilfs_sustat sustat;               426         struct nilfs_sustat sustat;
407         int ret;                                  427         int ret;
408                                                   428 
409         down_read(&nilfs->ns_segctor_sem);        429         down_read(&nilfs->ns_segctor_sem);
410         ret = nilfs_sufile_get_stat(nilfs->ns_    430         ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
411         up_read(&nilfs->ns_segctor_sem);          431         up_read(&nilfs->ns_segctor_sem);
412         if (ret < 0)                              432         if (ret < 0)
413                 return ret;                       433                 return ret;
414                                                   434 
415         if (copy_to_user(argp, &sustat, sizeof    435         if (copy_to_user(argp, &sustat, sizeof(sustat)))
416                 ret = -EFAULT;                    436                 ret = -EFAULT;
417         return ret;                               437         return ret;
418 }                                                 438 }
419                                                   439 
420 /**                                               440 /**
421  * nilfs_ioctl_do_get_vinfo - callback method     441  * nilfs_ioctl_do_get_vinfo - callback method getting virtual blocks info
422  * @nilfs: nilfs object                           442  * @nilfs: nilfs object
423  * @posp: *not used*                              443  * @posp: *not used*
424  * @flags: *not used*                             444  * @flags: *not used*
425  * @buf: buffer for storing array of nilfs_vin    445  * @buf: buffer for storing array of nilfs_vinfo structures
426  * @size: size in bytes of one vinfo item in a    446  * @size: size in bytes of one vinfo item in array
427  * @nmembs: count of vinfos in array              447  * @nmembs: count of vinfos in array
428  *                                                448  *
429  * Description: nilfs_ioctl_do_get_vinfo() fun    449  * Description: nilfs_ioctl_do_get_vinfo() function returns information
430  * on virtual block addresses. The NILFS_IOCTL    450  * on virtual block addresses. The NILFS_IOCTL_GET_VINFO ioctl is used
431  * by nilfs_cleanerd daemon.                      451  * by nilfs_cleanerd daemon.
432  *                                                452  *
433  * Return value: count of nilfs_vinfo structur    453  * Return value: count of nilfs_vinfo structures in output buffer.
434  */                                               454  */
435 static ssize_t                                    455 static ssize_t
436 nilfs_ioctl_do_get_vinfo(struct the_nilfs *nil    456 nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
437                          void *buf, size_t siz    457                          void *buf, size_t size, size_t nmembs)
438 {                                                 458 {
439         int ret;                                  459         int ret;
440                                                   460 
441         down_read(&nilfs->ns_segctor_sem);        461         down_read(&nilfs->ns_segctor_sem);
442         ret = nilfs_dat_get_vinfo(nilfs->ns_da    462         ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs);
443         up_read(&nilfs->ns_segctor_sem);          463         up_read(&nilfs->ns_segctor_sem);
444         return ret;                               464         return ret;
445 }                                                 465 }
446                                                   466 
447 /**                                               467 /**
448  * nilfs_ioctl_do_get_bdescs - callback method    468  * nilfs_ioctl_do_get_bdescs - callback method getting disk block descriptors
449  * @nilfs: nilfs object                           469  * @nilfs: nilfs object
450  * @posp: *not used*                              470  * @posp: *not used*
451  * @flags: *not used*                             471  * @flags: *not used*
452  * @buf: buffer for storing array of nilfs_bde    472  * @buf: buffer for storing array of nilfs_bdesc structures
453  * @size: size in bytes of one bdesc item in a    473  * @size: size in bytes of one bdesc item in array
454  * @nmembs: count of bdescs in array              474  * @nmembs: count of bdescs in array
455  *                                                475  *
456  * Description: nilfs_ioctl_do_get_bdescs() fu    476  * Description: nilfs_ioctl_do_get_bdescs() function returns information
457  * about descriptors of disk block numbers. Th    477  * about descriptors of disk block numbers. The NILFS_IOCTL_GET_BDESCS ioctl
458  * is used by nilfs_cleanerd daemon.              478  * is used by nilfs_cleanerd daemon.
459  *                                                479  *
460  * Return value: count of nilfs_bdescs structu    480  * Return value: count of nilfs_bdescs structures in output buffer.
461  */                                               481  */
462 static ssize_t                                    482 static ssize_t
463 nilfs_ioctl_do_get_bdescs(struct the_nilfs *ni    483 nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
464                           void *buf, size_t si    484                           void *buf, size_t size, size_t nmembs)
465 {                                                 485 {
466         struct nilfs_bmap *bmap = NILFS_I(nilf    486         struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
467         struct nilfs_bdesc *bdescs = buf;         487         struct nilfs_bdesc *bdescs = buf;
468         int ret, i;                               488         int ret, i;
469                                                   489 
470         down_read(&nilfs->ns_segctor_sem);        490         down_read(&nilfs->ns_segctor_sem);
471         for (i = 0; i < nmembs; i++) {            491         for (i = 0; i < nmembs; i++) {
472                 ret = nilfs_bmap_lookup_at_lev    492                 ret = nilfs_bmap_lookup_at_level(bmap,
473                                                   493                                                  bdescs[i].bd_offset,
474                                                   494                                                  bdescs[i].bd_level + 1,
475                                                   495                                                  &bdescs[i].bd_blocknr);
476                 if (ret < 0) {                    496                 if (ret < 0) {
477                         if (ret != -ENOENT) {     497                         if (ret != -ENOENT) {
478                                 up_read(&nilfs    498                                 up_read(&nilfs->ns_segctor_sem);
479                                 return ret;       499                                 return ret;
480                         }                         500                         }
481                         bdescs[i].bd_blocknr =    501                         bdescs[i].bd_blocknr = 0;
482                 }                                 502                 }
483         }                                         503         }
484         up_read(&nilfs->ns_segctor_sem);          504         up_read(&nilfs->ns_segctor_sem);
485         return nmembs;                            505         return nmembs;
486 }                                                 506 }
487                                                   507 
488 /**                                               508 /**
489  * nilfs_ioctl_get_bdescs - get disk block des    509  * nilfs_ioctl_get_bdescs - get disk block descriptors
490  * @inode: inode object                           510  * @inode: inode object
491  * @filp: file object                             511  * @filp: file object
492  * @cmd: ioctl's request code                     512  * @cmd: ioctl's request code
493  * @argp: pointer on argument from userspace      513  * @argp: pointer on argument from userspace
494  *                                                514  *
495  * Description: nilfs_ioctl_do_get_bdescs() fu    515  * Description: nilfs_ioctl_do_get_bdescs() function returns information
496  * about descriptors of disk block numbers. Th    516  * about descriptors of disk block numbers. The NILFS_IOCTL_GET_BDESCS ioctl
497  * is used by nilfs_cleanerd daemon.              517  * is used by nilfs_cleanerd daemon.
498  *                                                518  *
499  * Return Value: On success, 0 is returned, an    519  * Return Value: On success, 0 is returned, and disk block descriptors are
500  * copied into userspace pointer @argp. On err    520  * copied into userspace pointer @argp. On error, one of the following
501  * negative error codes is returned.              521  * negative error codes is returned.
502  *                                                522  *
503  * %-EINVAL - Invalid arguments from userspace    523  * %-EINVAL - Invalid arguments from userspace.
504  *                                                524  *
505  * %-EIO - I/O error.                             525  * %-EIO - I/O error.
506  *                                                526  *
507  * %-ENOMEM - Insufficient amount of memory av    527  * %-ENOMEM - Insufficient amount of memory available.
508  *                                                528  *
509  * %-EFAULT - Failure during getting disk bloc    529  * %-EFAULT - Failure during getting disk block descriptors.
510  */                                               530  */
511 static int nilfs_ioctl_get_bdescs(struct inode    531 static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
512                                   unsigned int    532                                   unsigned int cmd, void __user *argp)
513 {                                                 533 {
514         struct the_nilfs *nilfs = inode->i_sb-    534         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
515         struct nilfs_argv argv;                   535         struct nilfs_argv argv;
516         int ret;                                  536         int ret;
517                                                   537 
518         if (copy_from_user(&argv, argp, sizeof    538         if (copy_from_user(&argv, argp, sizeof(argv)))
519                 return -EFAULT;                   539                 return -EFAULT;
520                                                   540 
521         if (argv.v_size != sizeof(struct nilfs    541         if (argv.v_size != sizeof(struct nilfs_bdesc))
522                 return -EINVAL;                   542                 return -EINVAL;
523                                                   543 
524         ret = nilfs_ioctl_wrap_copy(nilfs, &ar    544         ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
525                                     nilfs_ioct    545                                     nilfs_ioctl_do_get_bdescs);
526         if (ret < 0)                              546         if (ret < 0)
527                 return ret;                       547                 return ret;
528                                                   548 
529         if (copy_to_user(argp, &argv, sizeof(a    549         if (copy_to_user(argp, &argv, sizeof(argv)))
530                 ret = -EFAULT;                    550                 ret = -EFAULT;
531         return ret;                               551         return ret;
532 }                                                 552 }
533                                                   553 
534 /**                                               554 /**
535  * nilfs_ioctl_move_inode_block - prepare data    555  * nilfs_ioctl_move_inode_block - prepare data/node block for moving by GC
536  * @inode: inode object                           556  * @inode: inode object
537  * @vdesc: descriptor of virtual block number     557  * @vdesc: descriptor of virtual block number
538  * @buffers: list of moving buffers               558  * @buffers: list of moving buffers
539  *                                                559  *
540  * Description: nilfs_ioctl_move_inode_block()    560  * Description: nilfs_ioctl_move_inode_block() function registers data/node
541  * buffer in the GC pagecache and submit read     561  * buffer in the GC pagecache and submit read request.
542  *                                                562  *
543  * Return Value: On success, 0 is returned. On    563  * Return Value: On success, 0 is returned. On error, one of the following
544  * negative error codes is returned.              564  * negative error codes is returned.
545  *                                                565  *
546  * %-EIO - I/O error.                             566  * %-EIO - I/O error.
547  *                                                567  *
548  * %-ENOMEM - Insufficient amount of memory av    568  * %-ENOMEM - Insufficient amount of memory available.
549  *                                                569  *
550  * %-ENOENT - Requested block doesn't exist.      570  * %-ENOENT - Requested block doesn't exist.
551  *                                                571  *
552  * %-EEXIST - Blocks conflict is detected.        572  * %-EEXIST - Blocks conflict is detected.
553  */                                               573  */
554 static int nilfs_ioctl_move_inode_block(struct    574 static int nilfs_ioctl_move_inode_block(struct inode *inode,
555                                         struct    575                                         struct nilfs_vdesc *vdesc,
556                                         struct    576                                         struct list_head *buffers)
557 {                                                 577 {
558         struct buffer_head *bh;                   578         struct buffer_head *bh;
559         int ret;                                  579         int ret;
560                                                   580 
561         if (vdesc->vd_flags == 0)                 581         if (vdesc->vd_flags == 0)
562                 ret = nilfs_gccache_submit_rea    582                 ret = nilfs_gccache_submit_read_data(
563                         inode, vdesc->vd_offse    583                         inode, vdesc->vd_offset, vdesc->vd_blocknr,
564                         vdesc->vd_vblocknr, &b    584                         vdesc->vd_vblocknr, &bh);
565         else                                      585         else
566                 ret = nilfs_gccache_submit_rea    586                 ret = nilfs_gccache_submit_read_node(
567                         inode, vdesc->vd_block    587                         inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh);
568                                                   588 
569         if (unlikely(ret < 0)) {                  589         if (unlikely(ret < 0)) {
570                 if (ret == -ENOENT)               590                 if (ret == -ENOENT)
571                         nilfs_crit(inode->i_sb !! 591                         printk(KERN_CRIT
572                                    "%s: invali !! 592                                "%s: invalid virtual block address (%s): "
573                                    __func__, v !! 593                                "ino=%llu, cno=%llu, offset=%llu, "
574                                    (unsigned l !! 594                                "blocknr=%llu, vblocknr=%llu\n",
575                                    (unsigned l !! 595                                __func__, vdesc->vd_flags ? "node" : "data",
576                                    (unsigned l !! 596                                (unsigned long long)vdesc->vd_ino,
577                                    (unsigned l !! 597                                (unsigned long long)vdesc->vd_cno,
578                                    (unsigned l !! 598                                (unsigned long long)vdesc->vd_offset,
                                                   >> 599                                (unsigned long long)vdesc->vd_blocknr,
                                                   >> 600                                (unsigned long long)vdesc->vd_vblocknr);
579                 return ret;                       601                 return ret;
580         }                                         602         }
581         if (unlikely(!list_empty(&bh->b_assoc_    603         if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
582                 nilfs_crit(inode->i_sb,        !! 604                 printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, "
583                            "%s: conflicting %s !! 605                        "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n",
584                            __func__, vdesc->vd !! 606                        __func__, vdesc->vd_flags ? "node" : "data",
585                            (unsigned long long !! 607                        (unsigned long long)vdesc->vd_ino,
586                            (unsigned long long !! 608                        (unsigned long long)vdesc->vd_cno,
587                            (unsigned long long !! 609                        (unsigned long long)vdesc->vd_offset,
588                            (unsigned long long !! 610                        (unsigned long long)vdesc->vd_blocknr,
589                            (unsigned long long !! 611                        (unsigned long long)vdesc->vd_vblocknr);
590                 brelse(bh);                       612                 brelse(bh);
591                 return -EEXIST;                   613                 return -EEXIST;
592         }                                         614         }
593         list_add_tail(&bh->b_assoc_buffers, bu    615         list_add_tail(&bh->b_assoc_buffers, buffers);
594         return 0;                                 616         return 0;
595 }                                                 617 }
596                                                   618 
597 /**                                               619 /**
598  * nilfs_ioctl_move_blocks - move valid inode'    620  * nilfs_ioctl_move_blocks - move valid inode's blocks during garbage collection
599  * @sb: superblock object                         621  * @sb: superblock object
600  * @argv: vector of arguments from userspace      622  * @argv: vector of arguments from userspace
601  * @buf: array of nilfs_vdesc structures          623  * @buf: array of nilfs_vdesc structures
602  *                                                624  *
603  * Description: nilfs_ioctl_move_blocks() func    625  * Description: nilfs_ioctl_move_blocks() function reads valid data/node
604  * blocks that garbage collector specified wit    626  * blocks that garbage collector specified with the array of nilfs_vdesc
605  * structures and stores them into page caches    627  * structures and stores them into page caches of GC inodes.
606  *                                                628  *
607  * Return Value: Number of processed nilfs_vde    629  * Return Value: Number of processed nilfs_vdesc structures or
608  * error code, otherwise.                         630  * error code, otherwise.
609  */                                               631  */
610 static int nilfs_ioctl_move_blocks(struct supe    632 static int nilfs_ioctl_move_blocks(struct super_block *sb,
611                                    struct nilf    633                                    struct nilfs_argv *argv, void *buf)
612 {                                                 634 {
613         size_t nmembs = argv->v_nmembs;           635         size_t nmembs = argv->v_nmembs;
614         struct the_nilfs *nilfs = sb->s_fs_inf    636         struct the_nilfs *nilfs = sb->s_fs_info;
615         struct inode *inode;                      637         struct inode *inode;
616         struct nilfs_vdesc *vdesc;                638         struct nilfs_vdesc *vdesc;
617         struct buffer_head *bh, *n;               639         struct buffer_head *bh, *n;
618         LIST_HEAD(buffers);                       640         LIST_HEAD(buffers);
619         ino_t ino;                                641         ino_t ino;
620         __u64 cno;                                642         __u64 cno;
621         int i, ret;                               643         int i, ret;
622                                                   644 
623         for (i = 0, vdesc = buf; i < nmembs; )    645         for (i = 0, vdesc = buf; i < nmembs; ) {
624                 ino = vdesc->vd_ino;              646                 ino = vdesc->vd_ino;
625                 cno = vdesc->vd_cno;              647                 cno = vdesc->vd_cno;
626                 inode = nilfs_iget_for_gc(sb,     648                 inode = nilfs_iget_for_gc(sb, ino, cno);
627                 if (IS_ERR(inode)) {              649                 if (IS_ERR(inode)) {
628                         ret = PTR_ERR(inode);     650                         ret = PTR_ERR(inode);
629                         goto failed;              651                         goto failed;
630                 }                                 652                 }
631                 if (list_empty(&NILFS_I(inode)    653                 if (list_empty(&NILFS_I(inode)->i_dirty)) {
632                         /*                        654                         /*
633                          * Add the inode to GC    655                          * Add the inode to GC inode list. Garbage Collection
634                          * is serialized and n    656                          * is serialized and no two processes manipulate the
635                          * list simultaneously    657                          * list simultaneously.
636                          */                       658                          */
637                         igrab(inode);             659                         igrab(inode);
638                         list_add(&NILFS_I(inod    660                         list_add(&NILFS_I(inode)->i_dirty,
639                                  &nilfs->ns_gc    661                                  &nilfs->ns_gc_inodes);
640                 }                                 662                 }
641                                                   663 
642                 do {                              664                 do {
643                         ret = nilfs_ioctl_move    665                         ret = nilfs_ioctl_move_inode_block(inode, vdesc,
644                                                   666                                                            &buffers);
645                         if (unlikely(ret < 0))    667                         if (unlikely(ret < 0)) {
646                                 iput(inode);      668                                 iput(inode);
647                                 goto failed;      669                                 goto failed;
648                         }                         670                         }
649                         vdesc++;                  671                         vdesc++;
650                 } while (++i < nmembs &&          672                 } while (++i < nmembs &&
651                          vdesc->vd_ino == ino     673                          vdesc->vd_ino == ino && vdesc->vd_cno == cno);
652                                                   674 
653                 iput(inode); /* The inode stil    675                 iput(inode); /* The inode still remains in GC inode list */
654         }                                         676         }
655                                                   677 
656         list_for_each_entry_safe(bh, n, &buffe    678         list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
657                 ret = nilfs_gccache_wait_and_m    679                 ret = nilfs_gccache_wait_and_mark_dirty(bh);
658                 if (unlikely(ret < 0)) {          680                 if (unlikely(ret < 0)) {
659                         WARN_ON(ret == -EEXIST    681                         WARN_ON(ret == -EEXIST);
660                         goto failed;              682                         goto failed;
661                 }                                 683                 }
662                 list_del_init(&bh->b_assoc_buf    684                 list_del_init(&bh->b_assoc_buffers);
663                 brelse(bh);                       685                 brelse(bh);
664         }                                         686         }
665         return nmembs;                            687         return nmembs;
666                                                   688 
667  failed:                                          689  failed:
668         list_for_each_entry_safe(bh, n, &buffe    690         list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
669                 list_del_init(&bh->b_assoc_buf    691                 list_del_init(&bh->b_assoc_buffers);
670                 brelse(bh);                       692                 brelse(bh);
671         }                                         693         }
672         return ret;                               694         return ret;
673 }                                                 695 }
674                                                   696 
675 /**                                               697 /**
676  * nilfs_ioctl_delete_checkpoints - delete che    698  * nilfs_ioctl_delete_checkpoints - delete checkpoints
677  * @nilfs: nilfs object                           699  * @nilfs: nilfs object
678  * @argv: vector of arguments from userspace      700  * @argv: vector of arguments from userspace
679  * @buf: array of periods of checkpoints numbe    701  * @buf: array of periods of checkpoints numbers
680  *                                                702  *
681  * Description: nilfs_ioctl_delete_checkpoints    703  * Description: nilfs_ioctl_delete_checkpoints() function deletes checkpoints
682  * in the period from p_start to p_end, exclud    704  * in the period from p_start to p_end, excluding p_end itself. The checkpoints
683  * which have been already deleted are ignored    705  * which have been already deleted are ignored.
684  *                                                706  *
685  * Return Value: Number of processed nilfs_per    707  * Return Value: Number of processed nilfs_period structures or
686  * error code, otherwise.                         708  * error code, otherwise.
687  *                                                709  *
688  * %-EIO - I/O error.                             710  * %-EIO - I/O error.
689  *                                                711  *
690  * %-ENOMEM - Insufficient amount of memory av    712  * %-ENOMEM - Insufficient amount of memory available.
691  *                                                713  *
692  * %-EINVAL - invalid checkpoints.                714  * %-EINVAL - invalid checkpoints.
693  */                                               715  */
694 static int nilfs_ioctl_delete_checkpoints(stru    716 static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
695                                           stru    717                                           struct nilfs_argv *argv, void *buf)
696 {                                                 718 {
697         size_t nmembs = argv->v_nmembs;           719         size_t nmembs = argv->v_nmembs;
698         struct inode *cpfile = nilfs->ns_cpfil    720         struct inode *cpfile = nilfs->ns_cpfile;
699         struct nilfs_period *periods = buf;       721         struct nilfs_period *periods = buf;
700         int ret, i;                               722         int ret, i;
701                                                   723 
702         for (i = 0; i < nmembs; i++) {            724         for (i = 0; i < nmembs; i++) {
703                 ret = nilfs_cpfile_delete_chec    725                 ret = nilfs_cpfile_delete_checkpoints(
704                         cpfile, periods[i].p_s    726                         cpfile, periods[i].p_start, periods[i].p_end);
705                 if (ret < 0)                      727                 if (ret < 0)
706                         return ret;               728                         return ret;
707         }                                         729         }
708         return nmembs;                            730         return nmembs;
709 }                                                 731 }
710                                                   732 
711 /**                                               733 /**
712  * nilfs_ioctl_free_vblocknrs - free virtual b    734  * nilfs_ioctl_free_vblocknrs - free virtual block numbers
713  * @nilfs: nilfs object                           735  * @nilfs: nilfs object
714  * @argv: vector of arguments from userspace      736  * @argv: vector of arguments from userspace
715  * @buf: array of virtual block numbers           737  * @buf: array of virtual block numbers
716  *                                                738  *
717  * Description: nilfs_ioctl_free_vblocknrs() f    739  * Description: nilfs_ioctl_free_vblocknrs() function frees
718  * the virtual block numbers specified by @buf    740  * the virtual block numbers specified by @buf and @argv->v_nmembs.
719  *                                                741  *
720  * Return Value: Number of processed virtual b    742  * Return Value: Number of processed virtual block numbers or
721  * error code, otherwise.                         743  * error code, otherwise.
722  *                                                744  *
723  * %-EIO - I/O error.                             745  * %-EIO - I/O error.
724  *                                                746  *
725  * %-ENOMEM - Insufficient amount of memory av    747  * %-ENOMEM - Insufficient amount of memory available.
726  *                                                748  *
727  * %-ENOENT - The virtual block number have no    749  * %-ENOENT - The virtual block number have not been allocated.
728  */                                               750  */
729 static int nilfs_ioctl_free_vblocknrs(struct t    751 static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
730                                       struct n    752                                       struct nilfs_argv *argv, void *buf)
731 {                                                 753 {
732         size_t nmembs = argv->v_nmembs;           754         size_t nmembs = argv->v_nmembs;
733         int ret;                                  755         int ret;
734                                                   756 
735         ret = nilfs_dat_freev(nilfs->ns_dat, b    757         ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs);
736                                                   758 
737         return (ret < 0) ? ret : nmembs;          759         return (ret < 0) ? ret : nmembs;
738 }                                                 760 }
739                                                   761 
740 /**                                               762 /**
741  * nilfs_ioctl_mark_blocks_dirty - mark blocks    763  * nilfs_ioctl_mark_blocks_dirty - mark blocks dirty
742  * @nilfs: nilfs object                           764  * @nilfs: nilfs object
743  * @argv: vector of arguments from userspace      765  * @argv: vector of arguments from userspace
744  * @buf: array of block descriptors               766  * @buf: array of block descriptors
745  *                                                767  *
746  * Description: nilfs_ioctl_mark_blocks_dirty(    768  * Description: nilfs_ioctl_mark_blocks_dirty() function marks
747  * metadata file or data blocks as dirty.         769  * metadata file or data blocks as dirty.
748  *                                                770  *
749  * Return Value: Number of processed block des    771  * Return Value: Number of processed block descriptors or
750  * error code, otherwise.                         772  * error code, otherwise.
751  *                                                773  *
752  * %-ENOMEM - Insufficient memory available.      774  * %-ENOMEM - Insufficient memory available.
753  *                                                775  *
754  * %-EIO - I/O error                              776  * %-EIO - I/O error
755  *                                                777  *
756  * %-ENOENT - the specified block does not exi    778  * %-ENOENT - the specified block does not exist (hole block)
757  */                                               779  */
758 static int nilfs_ioctl_mark_blocks_dirty(struc    780 static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
759                                          struc    781                                          struct nilfs_argv *argv, void *buf)
760 {                                                 782 {
761         size_t nmembs = argv->v_nmembs;           783         size_t nmembs = argv->v_nmembs;
762         struct nilfs_bmap *bmap = NILFS_I(nilf    784         struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
763         struct nilfs_bdesc *bdescs = buf;         785         struct nilfs_bdesc *bdescs = buf;
764         struct buffer_head *bh;                << 
765         int ret, i;                               786         int ret, i;
766                                                   787 
767         for (i = 0; i < nmembs; i++) {            788         for (i = 0; i < nmembs; i++) {
768                 /* XXX: use macro or inline fu    789                 /* XXX: use macro or inline func to check liveness */
769                 ret = nilfs_bmap_lookup_at_lev    790                 ret = nilfs_bmap_lookup_at_level(bmap,
770                                                   791                                                  bdescs[i].bd_offset,
771                                                   792                                                  bdescs[i].bd_level + 1,
772                                                   793                                                  &bdescs[i].bd_blocknr);
773                 if (ret < 0) {                    794                 if (ret < 0) {
774                         if (ret != -ENOENT)       795                         if (ret != -ENOENT)
775                                 return ret;       796                                 return ret;
776                         bdescs[i].bd_blocknr =    797                         bdescs[i].bd_blocknr = 0;
777                 }                                 798                 }
778                 if (bdescs[i].bd_blocknr != bd    799                 if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr)
779                         /* skip dead block */     800                         /* skip dead block */
780                         continue;                 801                         continue;
781                 if (bdescs[i].bd_level == 0) {    802                 if (bdescs[i].bd_level == 0) {
782                         ret = nilfs_mdt_get_bl !! 803                         ret = nilfs_mdt_mark_block_dirty(nilfs->ns_dat,
783                                                !! 804                                                          bdescs[i].bd_offset);
784                                                !! 805                         if (ret < 0) {
785                         if (unlikely(ret)) {   << 
786                                 WARN_ON(ret ==    806                                 WARN_ON(ret == -ENOENT);
787                                 return ret;       807                                 return ret;
788                         }                         808                         }
789                         mark_buffer_dirty(bh); << 
790                         nilfs_mdt_mark_dirty(n << 
791                         put_bh(bh);            << 
792                 } else {                          809                 } else {
793                         ret = nilfs_bmap_mark(    810                         ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
794                                                   811                                               bdescs[i].bd_level);
795                         if (ret < 0) {            812                         if (ret < 0) {
796                                 WARN_ON(ret ==    813                                 WARN_ON(ret == -ENOENT);
797                                 return ret;       814                                 return ret;
798                         }                         815                         }
799                 }                                 816                 }
800         }                                         817         }
801         return nmembs;                            818         return nmembs;
802 }                                                 819 }
803                                                   820 
804 int nilfs_ioctl_prepare_clean_segments(struct     821 int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
805                                        struct     822                                        struct nilfs_argv *argv, void **kbufs)
806 {                                                 823 {
807         const char *msg;                          824         const char *msg;
808         int ret;                                  825         int ret;
809                                                   826 
810         ret = nilfs_ioctl_delete_checkpoints(n    827         ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
811         if (ret < 0) {                            828         if (ret < 0) {
812                 /*                                829                 /*
813                  * can safely abort because ch    830                  * can safely abort because checkpoints can be removed
814                  * independently.                 831                  * independently.
815                  */                               832                  */
816                 msg = "cannot delete checkpoin    833                 msg = "cannot delete checkpoints";
817                 goto failed;                      834                 goto failed;
818         }                                         835         }
819         ret = nilfs_ioctl_free_vblocknrs(nilfs    836         ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
820         if (ret < 0) {                            837         if (ret < 0) {
821                 /*                                838                 /*
822                  * can safely abort because DA    839                  * can safely abort because DAT file is updated atomically
823                  * using a copy-on-write techn    840                  * using a copy-on-write technique.
824                  */                               841                  */
825                 msg = "cannot delete virtual b    842                 msg = "cannot delete virtual blocks from DAT file";
826                 goto failed;                      843                 goto failed;
827         }                                         844         }
828         ret = nilfs_ioctl_mark_blocks_dirty(ni    845         ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
829         if (ret < 0) {                            846         if (ret < 0) {
830                 /*                                847                 /*
831                  * can safely abort because th    848                  * can safely abort because the operation is nondestructive.
832                  */                               849                  */
833                 msg = "cannot mark copying blo    850                 msg = "cannot mark copying blocks dirty";
834                 goto failed;                      851                 goto failed;
835         }                                         852         }
836         return 0;                                 853         return 0;
837                                                   854 
838  failed:                                          855  failed:
839         nilfs_err(nilfs->ns_sb, "error %d prep !! 856         printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
                                                   >> 857                msg, ret);
840         return ret;                               858         return ret;
841 }                                                 859 }
842                                                   860 
843 /**                                               861 /**
844  * nilfs_ioctl_clean_segments - clean segments    862  * nilfs_ioctl_clean_segments - clean segments
845  * @inode: inode object                           863  * @inode: inode object
846  * @filp: file object                             864  * @filp: file object
847  * @cmd: ioctl's request code                     865  * @cmd: ioctl's request code
848  * @argp: pointer on argument from userspace      866  * @argp: pointer on argument from userspace
849  *                                                867  *
850  * Description: nilfs_ioctl_clean_segments() f    868  * Description: nilfs_ioctl_clean_segments() function makes garbage
851  * collection operation in the environment of     869  * collection operation in the environment of requested parameters
852  * from userspace. The NILFS_IOCTL_CLEAN_SEGME    870  * from userspace. The NILFS_IOCTL_CLEAN_SEGMENTS ioctl is used by
853  * nilfs_cleanerd daemon.                         871  * nilfs_cleanerd daemon.
854  *                                                872  *
855  * Return Value: On success, 0 is returned or     873  * Return Value: On success, 0 is returned or error code, otherwise.
856  */                                               874  */
857 static int nilfs_ioctl_clean_segments(struct i    875 static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
858                                       unsigned    876                                       unsigned int cmd, void __user *argp)
859 {                                                 877 {
860         struct nilfs_argv argv[5];                878         struct nilfs_argv argv[5];
861         static const size_t argsz[5] = {          879         static const size_t argsz[5] = {
862                 sizeof(struct nilfs_vdesc),       880                 sizeof(struct nilfs_vdesc),
863                 sizeof(struct nilfs_period),      881                 sizeof(struct nilfs_period),
864                 sizeof(__u64),                    882                 sizeof(__u64),
865                 sizeof(struct nilfs_bdesc),       883                 sizeof(struct nilfs_bdesc),
866                 sizeof(__u64),                    884                 sizeof(__u64),
867         };                                        885         };
868         void __user *base;                        886         void __user *base;
869         void *kbufs[5];                           887         void *kbufs[5];
870         struct the_nilfs *nilfs;                  888         struct the_nilfs *nilfs;
871         size_t len, nsegs;                        889         size_t len, nsegs;
872         int n, ret;                               890         int n, ret;
873                                                   891 
874         if (!capable(CAP_SYS_ADMIN))              892         if (!capable(CAP_SYS_ADMIN))
875                 return -EPERM;                    893                 return -EPERM;
876                                                   894 
877         ret = mnt_want_write_file(filp);          895         ret = mnt_want_write_file(filp);
878         if (ret)                                  896         if (ret)
879                 return ret;                       897                 return ret;
880                                                   898 
881         ret = -EFAULT;                            899         ret = -EFAULT;
882         if (copy_from_user(argv, argp, sizeof(    900         if (copy_from_user(argv, argp, sizeof(argv)))
883                 goto out;                         901                 goto out;
884                                                   902 
885         ret = -EINVAL;                            903         ret = -EINVAL;
886         nsegs = argv[4].v_nmembs;                 904         nsegs = argv[4].v_nmembs;
887         if (argv[4].v_size != argsz[4])           905         if (argv[4].v_size != argsz[4])
888                 goto out;                         906                 goto out;
                                                   >> 907         if (nsegs > UINT_MAX / sizeof(__u64))
                                                   >> 908                 goto out;
889                                                   909 
890         /*                                        910         /*
891          * argv[4] points to segment numbers t    911          * argv[4] points to segment numbers this ioctl cleans.  We
892          * use kmalloc() for its buffer becaus !! 912          * use kmalloc() for its buffer because memory used for the
893          * segment numbers is small enough.    !! 913          * segment numbers is enough small.
894          */                                       914          */
895         kbufs[4] = memdup_array_user((void __u !! 915         kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
896                                      nsegs, si !! 916                                nsegs * sizeof(__u64));
897         if (IS_ERR(kbufs[4])) {                   917         if (IS_ERR(kbufs[4])) {
898                 ret = PTR_ERR(kbufs[4]);          918                 ret = PTR_ERR(kbufs[4]);
899                 goto out;                         919                 goto out;
900         }                                         920         }
901         nilfs = inode->i_sb->s_fs_info;           921         nilfs = inode->i_sb->s_fs_info;
902                                                   922 
903         for (n = 0; n < 4; n++) {                 923         for (n = 0; n < 4; n++) {
904                 ret = -EINVAL;                    924                 ret = -EINVAL;
905                 if (argv[n].v_size != argsz[n]    925                 if (argv[n].v_size != argsz[n])
906                         goto out_free;            926                         goto out_free;
907                                                   927 
908                 if (argv[n].v_nmembs > nsegs *    928                 if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
909                         goto out_free;            929                         goto out_free;
910                                                   930 
911                 if (argv[n].v_nmembs >= UINT_M    931                 if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size)
912                         goto out_free;            932                         goto out_free;
913                                                   933 
914                 len = argv[n].v_size * argv[n]    934                 len = argv[n].v_size * argv[n].v_nmembs;
915                 base = (void __user *)(unsigne    935                 base = (void __user *)(unsigned long)argv[n].v_base;
916                 if (len == 0) {                   936                 if (len == 0) {
917                         kbufs[n] = NULL;          937                         kbufs[n] = NULL;
918                         continue;                 938                         continue;
919                 }                                 939                 }
920                                                   940 
921                 kbufs[n] = vmalloc(len);          941                 kbufs[n] = vmalloc(len);
922                 if (!kbufs[n]) {                  942                 if (!kbufs[n]) {
923                         ret = -ENOMEM;            943                         ret = -ENOMEM;
924                         goto out_free;            944                         goto out_free;
925                 }                                 945                 }
926                 if (copy_from_user(kbufs[n], b    946                 if (copy_from_user(kbufs[n], base, len)) {
927                         ret = -EFAULT;            947                         ret = -EFAULT;
928                         vfree(kbufs[n]);          948                         vfree(kbufs[n]);
929                         goto out_free;            949                         goto out_free;
930                 }                                 950                 }
931         }                                         951         }
932                                                   952 
933         /*                                        953         /*
934          * nilfs_ioctl_move_blocks() will call    954          * nilfs_ioctl_move_blocks() will call nilfs_iget_for_gc(),
935          * which will operates an inode list w    955          * which will operates an inode list without blocking.
936          * To protect the list from concurrent    956          * To protect the list from concurrent operations,
937          * nilfs_ioctl_move_blocks should be a    957          * nilfs_ioctl_move_blocks should be atomic operation.
938          */                                       958          */
939         if (test_and_set_bit(THE_NILFS_GC_RUNN    959         if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
940                 ret = -EBUSY;                     960                 ret = -EBUSY;
941                 goto out_free;                    961                 goto out_free;
942         }                                         962         }
943                                                   963 
944         ret = nilfs_ioctl_move_blocks(inode->i    964         ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
945         if (ret < 0) {                         !! 965         if (ret < 0)
946                 nilfs_err(inode->i_sb,         !! 966                 printk(KERN_ERR "NILFS: GC failed during preparation: "
947                           "error %d preparing  !! 967                         "cannot read source blocks: err=%d\n", ret);
948                           ret);                !! 968         else {
949         } else {                               << 
950                 if (nilfs_sb_need_update(nilfs    969                 if (nilfs_sb_need_update(nilfs))
951                         set_nilfs_discontinued    970                         set_nilfs_discontinued(nilfs);
952                 ret = nilfs_clean_segments(ino    971                 ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
953         }                                         972         }
954                                                   973 
955         nilfs_remove_all_gcinodes(nilfs);         974         nilfs_remove_all_gcinodes(nilfs);
956         clear_nilfs_gc_running(nilfs);            975         clear_nilfs_gc_running(nilfs);
957                                                   976 
958 out_free:                                         977 out_free:
959         while (--n >= 0)                          978         while (--n >= 0)
960                 vfree(kbufs[n]);                  979                 vfree(kbufs[n]);
961         kfree(kbufs[4]);                          980         kfree(kbufs[4]);
962 out:                                              981 out:
963         mnt_drop_write_file(filp);                982         mnt_drop_write_file(filp);
964         return ret;                               983         return ret;
965 }                                                 984 }
966                                                   985 
967 /**                                               986 /**
968  * nilfs_ioctl_sync - make a checkpoint           987  * nilfs_ioctl_sync - make a checkpoint
969  * @inode: inode object                           988  * @inode: inode object
970  * @filp: file object                             989  * @filp: file object
971  * @cmd: ioctl's request code                     990  * @cmd: ioctl's request code
972  * @argp: pointer on argument from userspace      991  * @argp: pointer on argument from userspace
973  *                                                992  *
974  * Description: nilfs_ioctl_sync() function co    993  * Description: nilfs_ioctl_sync() function constructs a logical segment
975  * for checkpointing.  This function guarantee    994  * for checkpointing.  This function guarantees that all modified data
976  * and metadata are written out to the device     995  * and metadata are written out to the device when it successfully
977  * returned.                                      996  * returned.
978  *                                                997  *
979  * Return Value: On success, 0 is retured. On     998  * Return Value: On success, 0 is retured. On errors, one of the following
980  * negative error code is returned.               999  * negative error code is returned.
981  *                                                1000  *
982  * %-EROFS - Read only filesystem.                1001  * %-EROFS - Read only filesystem.
983  *                                                1002  *
984  * %-EIO - I/O error                              1003  * %-EIO - I/O error
985  *                                                1004  *
986  * %-ENOSPC - No space left on device (only in    1005  * %-ENOSPC - No space left on device (only in a panic state).
987  *                                                1006  *
988  * %-ERESTARTSYS - Interrupted.                   1007  * %-ERESTARTSYS - Interrupted.
989  *                                                1008  *
990  * %-ENOMEM - Insufficient memory available.      1009  * %-ENOMEM - Insufficient memory available.
991  *                                                1010  *
992  * %-EFAULT - Failure during execution of requ    1011  * %-EFAULT - Failure during execution of requested operation.
993  */                                               1012  */
994 static int nilfs_ioctl_sync(struct inode *inod    1013 static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
995                             unsigned int cmd,     1014                             unsigned int cmd, void __user *argp)
996 {                                                 1015 {
997         __u64 cno;                                1016         __u64 cno;
998         int ret;                                  1017         int ret;
999         struct the_nilfs *nilfs;                  1018         struct the_nilfs *nilfs;
1000                                                  1019 
1001         ret = nilfs_construct_segment(inode->    1020         ret = nilfs_construct_segment(inode->i_sb);
1002         if (ret < 0)                             1021         if (ret < 0)
1003                 return ret;                      1022                 return ret;
1004                                                  1023 
1005         nilfs = inode->i_sb->s_fs_info;          1024         nilfs = inode->i_sb->s_fs_info;
1006         ret = nilfs_flush_device(nilfs);         1025         ret = nilfs_flush_device(nilfs);
1007         if (ret < 0)                             1026         if (ret < 0)
1008                 return ret;                      1027                 return ret;
1009                                                  1028 
1010         if (argp != NULL) {                      1029         if (argp != NULL) {
1011                 down_read(&nilfs->ns_segctor_    1030                 down_read(&nilfs->ns_segctor_sem);
1012                 cno = nilfs->ns_cno - 1;         1031                 cno = nilfs->ns_cno - 1;
1013                 up_read(&nilfs->ns_segctor_se    1032                 up_read(&nilfs->ns_segctor_sem);
1014                 if (copy_to_user(argp, &cno,     1033                 if (copy_to_user(argp, &cno, sizeof(cno)))
1015                         return -EFAULT;          1034                         return -EFAULT;
1016         }                                        1035         }
1017         return 0;                                1036         return 0;
1018 }                                                1037 }
1019                                                  1038 
1020 /**                                              1039 /**
1021  * nilfs_ioctl_resize - resize NILFS2 volume     1040  * nilfs_ioctl_resize - resize NILFS2 volume
1022  * @inode: inode object                          1041  * @inode: inode object
1023  * @filp: file object                            1042  * @filp: file object
1024  * @argp: pointer on argument from userspace     1043  * @argp: pointer on argument from userspace
1025  *                                               1044  *
1026  * Return Value: On success, 0 is returned or    1045  * Return Value: On success, 0 is returned or error code, otherwise.
1027  */                                              1046  */
1028 static int nilfs_ioctl_resize(struct inode *i    1047 static int nilfs_ioctl_resize(struct inode *inode, struct file *filp,
1029                               void __user *ar    1048                               void __user *argp)
1030 {                                                1049 {
1031         __u64 newsize;                           1050         __u64 newsize;
1032         int ret = -EPERM;                        1051         int ret = -EPERM;
1033                                                  1052 
1034         if (!capable(CAP_SYS_ADMIN))             1053         if (!capable(CAP_SYS_ADMIN))
1035                 goto out;                        1054                 goto out;
1036                                                  1055 
1037         ret = mnt_want_write_file(filp);         1056         ret = mnt_want_write_file(filp);
1038         if (ret)                                 1057         if (ret)
1039                 goto out;                        1058                 goto out;
1040                                                  1059 
1041         ret = -EFAULT;                           1060         ret = -EFAULT;
1042         if (copy_from_user(&newsize, argp, si    1061         if (copy_from_user(&newsize, argp, sizeof(newsize)))
1043                 goto out_drop_write;             1062                 goto out_drop_write;
1044                                                  1063 
1045         ret = nilfs_resize_fs(inode->i_sb, ne    1064         ret = nilfs_resize_fs(inode->i_sb, newsize);
1046                                                  1065 
1047 out_drop_write:                                  1066 out_drop_write:
1048         mnt_drop_write_file(filp);               1067         mnt_drop_write_file(filp);
1049 out:                                             1068 out:
1050         return ret;                              1069         return ret;
1051 }                                                1070 }
1052                                                  1071 
1053 /**                                              1072 /**
1054  * nilfs_ioctl_trim_fs() - trim ioctl handle     1073  * nilfs_ioctl_trim_fs() - trim ioctl handle function
1055  * @inode: inode object                          1074  * @inode: inode object
1056  * @argp: pointer on argument from userspace     1075  * @argp: pointer on argument from userspace
1057  *                                               1076  *
1058  * Description: nilfs_ioctl_trim_fs is the FI !! 1077  * Decription: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It
1059  * checks the arguments from userspace and ca    1078  * checks the arguments from userspace and calls nilfs_sufile_trim_fs, which
1060  * performs the actual trim operation.           1079  * performs the actual trim operation.
1061  *                                               1080  *
1062  * Return Value: On success, 0 is returned or    1081  * Return Value: On success, 0 is returned or negative error code, otherwise.
1063  */                                              1082  */
1064 static int nilfs_ioctl_trim_fs(struct inode *    1083 static int nilfs_ioctl_trim_fs(struct inode *inode, void __user *argp)
1065 {                                                1084 {
1066         struct the_nilfs *nilfs = inode->i_sb    1085         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
                                                   >> 1086         struct request_queue *q = bdev_get_queue(nilfs->ns_bdev);
1067         struct fstrim_range range;               1087         struct fstrim_range range;
1068         int ret;                                 1088         int ret;
1069                                                  1089 
1070         if (!capable(CAP_SYS_ADMIN))             1090         if (!capable(CAP_SYS_ADMIN))
1071                 return -EPERM;                   1091                 return -EPERM;
1072                                                  1092 
1073         if (!bdev_max_discard_sectors(nilfs-> !! 1093         if (!blk_queue_discard(q))
1074                 return -EOPNOTSUPP;              1094                 return -EOPNOTSUPP;
1075                                                  1095 
1076         if (copy_from_user(&range, argp, size    1096         if (copy_from_user(&range, argp, sizeof(range)))
1077                 return -EFAULT;                  1097                 return -EFAULT;
1078                                                  1098 
1079         range.minlen = max_t(u64, range.minle !! 1099         range.minlen = max_t(u64, range.minlen, q->limits.discard_granularity);
1080                              bdev_discard_gra << 
1081                                                  1100 
1082         down_read(&nilfs->ns_segctor_sem);       1101         down_read(&nilfs->ns_segctor_sem);
1083         ret = nilfs_sufile_trim_fs(nilfs->ns_    1102         ret = nilfs_sufile_trim_fs(nilfs->ns_sufile, &range);
1084         up_read(&nilfs->ns_segctor_sem);         1103         up_read(&nilfs->ns_segctor_sem);
1085                                                  1104 
1086         if (ret < 0)                             1105         if (ret < 0)
1087                 return ret;                      1106                 return ret;
1088                                                  1107 
1089         if (copy_to_user(argp, &range, sizeof    1108         if (copy_to_user(argp, &range, sizeof(range)))
1090                 return -EFAULT;                  1109                 return -EFAULT;
1091                                                  1110 
1092         return 0;                                1111         return 0;
1093 }                                                1112 }
1094                                                  1113 
1095 /**                                              1114 /**
1096  * nilfs_ioctl_set_alloc_range - limit range     1115  * nilfs_ioctl_set_alloc_range - limit range of segments to be allocated
1097  * @inode: inode object                          1116  * @inode: inode object
1098  * @argp: pointer on argument from userspace     1117  * @argp: pointer on argument from userspace
1099  *                                               1118  *
1100  * Description: nilfs_ioctl_set_alloc_range() !! 1119  * Decription: nilfs_ioctl_set_alloc_range() function defines lower limit
1101  * of segments in bytes and upper limit of se    1120  * of segments in bytes and upper limit of segments in bytes.
1102  * The NILFS_IOCTL_SET_ALLOC_RANGE is used by    1121  * The NILFS_IOCTL_SET_ALLOC_RANGE is used by nilfs_resize utility.
1103  *                                               1122  *
1104  * Return Value: On success, 0 is returned or    1123  * Return Value: On success, 0 is returned or error code, otherwise.
1105  */                                              1124  */
1106 static int nilfs_ioctl_set_alloc_range(struct    1125 static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp)
1107 {                                                1126 {
1108         struct the_nilfs *nilfs = inode->i_sb    1127         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1109         __u64 range[2];                          1128         __u64 range[2];
1110         __u64 minseg, maxseg;                    1129         __u64 minseg, maxseg;
1111         unsigned long segbytes;                  1130         unsigned long segbytes;
1112         int ret = -EPERM;                        1131         int ret = -EPERM;
1113                                                  1132 
1114         if (!capable(CAP_SYS_ADMIN))             1133         if (!capable(CAP_SYS_ADMIN))
1115                 goto out;                        1134                 goto out;
1116                                                  1135 
1117         ret = -EFAULT;                           1136         ret = -EFAULT;
1118         if (copy_from_user(range, argp, sizeo    1137         if (copy_from_user(range, argp, sizeof(__u64[2])))
1119                 goto out;                        1138                 goto out;
1120                                                  1139 
1121         ret = -ERANGE;                           1140         ret = -ERANGE;
1122         if (range[1] > bdev_nr_bytes(inode->i !! 1141         if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode))
1123                 goto out;                        1142                 goto out;
1124                                                  1143 
1125         segbytes = nilfs->ns_blocks_per_segme    1144         segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize;
1126                                                  1145 
1127         minseg = range[0] + segbytes - 1;        1146         minseg = range[0] + segbytes - 1;
1128         minseg = div64_ul(minseg, segbytes);  !! 1147         do_div(minseg, segbytes);
1129                                               << 
1130         if (range[1] < 4096)                  << 
1131                 goto out;                     << 
1132                                               << 
1133         maxseg = NILFS_SB2_OFFSET_BYTES(range    1148         maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
1134         if (maxseg < segbytes)                !! 1149         do_div(maxseg, segbytes);
1135                 goto out;                     << 
1136                                               << 
1137         maxseg = div64_ul(maxseg, segbytes);  << 
1138         maxseg--;                                1150         maxseg--;
1139                                                  1151 
1140         ret = nilfs_sufile_set_alloc_range(ni    1152         ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg);
1141 out:                                             1153 out:
1142         return ret;                              1154         return ret;
1143 }                                                1155 }
1144                                                  1156 
1145 /**                                              1157 /**
1146  * nilfs_ioctl_get_info - wrapping function o    1158  * nilfs_ioctl_get_info - wrapping function of get metadata info
1147  * @inode: inode object                          1159  * @inode: inode object
1148  * @filp: file object                            1160  * @filp: file object
1149  * @cmd: ioctl's request code                    1161  * @cmd: ioctl's request code
1150  * @argp: pointer on argument from userspace     1162  * @argp: pointer on argument from userspace
1151  * @membsz: size of an item in bytes             1163  * @membsz: size of an item in bytes
1152  * @dofunc: concrete function of getting meta    1164  * @dofunc: concrete function of getting metadata info
1153  *                                               1165  *
1154  * Description: nilfs_ioctl_get_info() gets m    1166  * Description: nilfs_ioctl_get_info() gets metadata info by means of
1155  * calling dofunc() function.                    1167  * calling dofunc() function.
1156  *                                               1168  *
1157  * Return Value: On success, 0 is returned an    1169  * Return Value: On success, 0 is returned and requested metadata info
1158  * is copied into userspace. On error, one of    1170  * is copied into userspace. On error, one of the following
1159  * negative error codes is returned.             1171  * negative error codes is returned.
1160  *                                               1172  *
1161  * %-EINVAL - Invalid arguments from userspac    1173  * %-EINVAL - Invalid arguments from userspace.
1162  *                                               1174  *
1163  * %-ENOMEM - Insufficient amount of memory a    1175  * %-ENOMEM - Insufficient amount of memory available.
1164  *                                               1176  *
1165  * %-EFAULT - Failure during execution of req    1177  * %-EFAULT - Failure during execution of requested operation.
1166  */                                              1178  */
1167 static int nilfs_ioctl_get_info(struct inode     1179 static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
1168                                 unsigned int     1180                                 unsigned int cmd, void __user *argp,
1169                                 size_t membsz    1181                                 size_t membsz,
1170                                 ssize_t (*dof    1182                                 ssize_t (*dofunc)(struct the_nilfs *,
1171                                                  1183                                                   __u64 *, int,
1172                                                  1184                                                   void *, size_t, size_t))
1173                                                  1185 
1174 {                                                1186 {
1175         struct the_nilfs *nilfs = inode->i_sb    1187         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1176         struct nilfs_argv argv;                  1188         struct nilfs_argv argv;
1177         int ret;                                 1189         int ret;
1178                                                  1190 
1179         if (copy_from_user(&argv, argp, sizeo    1191         if (copy_from_user(&argv, argp, sizeof(argv)))
1180                 return -EFAULT;                  1192                 return -EFAULT;
1181                                                  1193 
1182         if (argv.v_size < membsz)                1194         if (argv.v_size < membsz)
1183                 return -EINVAL;                  1195                 return -EINVAL;
1184                                                  1196 
1185         ret = nilfs_ioctl_wrap_copy(nilfs, &a    1197         ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
1186         if (ret < 0)                             1198         if (ret < 0)
1187                 return ret;                      1199                 return ret;
1188                                                  1200 
1189         if (copy_to_user(argp, &argv, sizeof(    1201         if (copy_to_user(argp, &argv, sizeof(argv)))
1190                 ret = -EFAULT;                   1202                 ret = -EFAULT;
1191         return ret;                              1203         return ret;
1192 }                                                1204 }
1193                                                  1205 
1194 /**                                              1206 /**
1195  * nilfs_ioctl_set_suinfo - set segment usage    1207  * nilfs_ioctl_set_suinfo - set segment usage info
1196  * @inode: inode object                          1208  * @inode: inode object
1197  * @filp: file object                            1209  * @filp: file object
1198  * @cmd: ioctl's request code                    1210  * @cmd: ioctl's request code
1199  * @argp: pointer on argument from userspace     1211  * @argp: pointer on argument from userspace
1200  *                                               1212  *
1201  * Description: Expects an array of nilfs_sui    1213  * Description: Expects an array of nilfs_suinfo_update structures
1202  * encapsulated in nilfs_argv and updates the    1214  * encapsulated in nilfs_argv and updates the segment usage info
1203  * according to the flags in nilfs_suinfo_upd    1215  * according to the flags in nilfs_suinfo_update.
1204  *                                               1216  *
1205  * Return Value: On success, 0 is returned. O    1217  * Return Value: On success, 0 is returned. On error, one of the
1206  * following negative error codes is returned    1218  * following negative error codes is returned.
1207  *                                               1219  *
1208  * %-EPERM - Not enough permissions              1220  * %-EPERM - Not enough permissions
1209  *                                               1221  *
1210  * %-EFAULT - Error copying input data           1222  * %-EFAULT - Error copying input data
1211  *                                               1223  *
1212  * %-EIO - I/O error.                            1224  * %-EIO - I/O error.
1213  *                                               1225  *
1214  * %-ENOMEM - Insufficient amount of memory a    1226  * %-ENOMEM - Insufficient amount of memory available.
1215  *                                               1227  *
1216  * %-EINVAL - Invalid values in input (segmen    1228  * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
1217  */                                              1229  */
1218 static int nilfs_ioctl_set_suinfo(struct inod    1230 static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
1219                                 unsigned int     1231                                 unsigned int cmd, void __user *argp)
1220 {                                                1232 {
1221         struct the_nilfs *nilfs = inode->i_sb    1233         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1222         struct nilfs_transaction_info ti;        1234         struct nilfs_transaction_info ti;
1223         struct nilfs_argv argv;                  1235         struct nilfs_argv argv;
1224         size_t len;                              1236         size_t len;
1225         void __user *base;                       1237         void __user *base;
1226         void *kbuf;                              1238         void *kbuf;
1227         int ret;                                 1239         int ret;
1228                                                  1240 
1229         if (!capable(CAP_SYS_ADMIN))             1241         if (!capable(CAP_SYS_ADMIN))
1230                 return -EPERM;                   1242                 return -EPERM;
1231                                                  1243 
1232         ret = mnt_want_write_file(filp);         1244         ret = mnt_want_write_file(filp);
1233         if (ret)                                 1245         if (ret)
1234                 return ret;                      1246                 return ret;
1235                                                  1247 
1236         ret = -EFAULT;                           1248         ret = -EFAULT;
1237         if (copy_from_user(&argv, argp, sizeo    1249         if (copy_from_user(&argv, argp, sizeof(argv)))
1238                 goto out;                        1250                 goto out;
1239                                                  1251 
1240         ret = -EINVAL;                           1252         ret = -EINVAL;
1241         if (argv.v_size < sizeof(struct nilfs    1253         if (argv.v_size < sizeof(struct nilfs_suinfo_update))
1242                 goto out;                        1254                 goto out;
1243                                                  1255 
1244         if (argv.v_nmembs > nilfs->ns_nsegmen    1256         if (argv.v_nmembs > nilfs->ns_nsegments)
1245                 goto out;                        1257                 goto out;
1246                                                  1258 
1247         if (argv.v_nmembs >= UINT_MAX / argv.    1259         if (argv.v_nmembs >= UINT_MAX / argv.v_size)
1248                 goto out;                        1260                 goto out;
1249                                                  1261 
1250         len = argv.v_size * argv.v_nmembs;       1262         len = argv.v_size * argv.v_nmembs;
1251         if (!len) {                              1263         if (!len) {
1252                 ret = 0;                         1264                 ret = 0;
1253                 goto out;                        1265                 goto out;
1254         }                                        1266         }
1255                                                  1267 
1256         base = (void __user *)(unsigned long)    1268         base = (void __user *)(unsigned long)argv.v_base;
1257         kbuf = vmalloc(len);                     1269         kbuf = vmalloc(len);
1258         if (!kbuf) {                             1270         if (!kbuf) {
1259                 ret = -ENOMEM;                   1271                 ret = -ENOMEM;
1260                 goto out;                        1272                 goto out;
1261         }                                        1273         }
1262                                                  1274 
1263         if (copy_from_user(kbuf, base, len))     1275         if (copy_from_user(kbuf, base, len)) {
1264                 ret = -EFAULT;                   1276                 ret = -EFAULT;
1265                 goto out_free;                   1277                 goto out_free;
1266         }                                        1278         }
1267                                                  1279 
1268         nilfs_transaction_begin(inode->i_sb,     1280         nilfs_transaction_begin(inode->i_sb, &ti, 0);
1269         ret = nilfs_sufile_set_suinfo(nilfs->    1281         ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
1270                         argv.v_nmembs);          1282                         argv.v_nmembs);
1271         if (unlikely(ret < 0))                   1283         if (unlikely(ret < 0))
1272                 nilfs_transaction_abort(inode    1284                 nilfs_transaction_abort(inode->i_sb);
1273         else                                     1285         else
1274                 nilfs_transaction_commit(inod    1286                 nilfs_transaction_commit(inode->i_sb); /* never fails */
1275                                                  1287 
1276 out_free:                                        1288 out_free:
1277         vfree(kbuf);                             1289         vfree(kbuf);
1278 out:                                             1290 out:
1279         mnt_drop_write_file(filp);               1291         mnt_drop_write_file(filp);
1280         return ret;                              1292         return ret;
1281 }                                                1293 }
1282                                                  1294 
1283 /**                                           << 
1284  * nilfs_ioctl_get_fslabel - get the volume n << 
1285  * @sb:   super block instance                << 
1286  * @argp: pointer to userspace memory where t << 
1287  *                                            << 
1288  * Return: 0 on success, %-EFAULT if copying  << 
1289  */                                           << 
1290 static int nilfs_ioctl_get_fslabel(struct sup << 
1291 {                                             << 
1292         struct the_nilfs *nilfs = sb->s_fs_in << 
1293         char label[NILFS_MAX_VOLUME_NAME + 1] << 
1294                                               << 
1295         BUILD_BUG_ON(NILFS_MAX_VOLUME_NAME >= << 
1296                                               << 
1297         down_read(&nilfs->ns_sem);            << 
1298         memtostr_pad(label, nilfs->ns_sbp[0]- << 
1299         up_read(&nilfs->ns_sem);              << 
1300                                               << 
1301         if (copy_to_user(argp, label, sizeof( << 
1302                 return -EFAULT;               << 
1303         return 0;                             << 
1304 }                                             << 
1305                                               << 
1306 /**                                           << 
1307  * nilfs_ioctl_set_fslabel - set the volume n << 
1308  * @sb:   super block instance                << 
1309  * @filp: file object                         << 
1310  * @argp: pointer to userspace memory that co << 
1311  *                                            << 
1312  * Return: 0 on success, or the following neg << 
1313  * * %-EFAULT   - Error copying input data.   << 
1314  * * %-EINVAL   - Label length exceeds record << 
1315  * * %-EIO      - I/O error.                  << 
1316  * * %-EPERM    - Operation not permitted (in << 
1317  * * %-EROFS    - Read only file system.      << 
1318  */                                           << 
1319 static int nilfs_ioctl_set_fslabel(struct sup << 
1320                                    void __use << 
1321 {                                             << 
1322         char label[NILFS_MAX_VOLUME_NAME + 1] << 
1323         struct the_nilfs *nilfs = sb->s_fs_in << 
1324         struct nilfs_super_block **sbp;       << 
1325         size_t len;                           << 
1326         int ret;                              << 
1327                                               << 
1328         if (!capable(CAP_SYS_ADMIN))          << 
1329                 return -EPERM;                << 
1330                                               << 
1331         ret = mnt_want_write_file(filp);      << 
1332         if (ret)                              << 
1333                 return ret;                   << 
1334                                               << 
1335         if (copy_from_user(label, argp, NILFS << 
1336                 ret = -EFAULT;                << 
1337                 goto out_drop_write;          << 
1338         }                                     << 
1339                                               << 
1340         len = strnlen(label, NILFS_MAX_VOLUME << 
1341         if (len > NILFS_MAX_VOLUME_NAME) {    << 
1342                 nilfs_err(sb, "unable to set  << 
1343                           NILFS_MAX_VOLUME_NA << 
1344                 ret = -EINVAL;                << 
1345                 goto out_drop_write;          << 
1346         }                                     << 
1347                                               << 
1348         down_write(&nilfs->ns_sem);           << 
1349         sbp = nilfs_prepare_super(sb, false); << 
1350         if (unlikely(!sbp)) {                 << 
1351                 ret = -EIO;                   << 
1352                 goto out_unlock;              << 
1353         }                                     << 
1354                                               << 
1355         strtomem_pad(sbp[0]->s_volume_name, l << 
1356         if (sbp[1])                           << 
1357                 strtomem_pad(sbp[1]->s_volume << 
1358                                               << 
1359         ret = nilfs_commit_super(sb, NILFS_SB << 
1360                                               << 
1361 out_unlock:                                   << 
1362         up_write(&nilfs->ns_sem);             << 
1363 out_drop_write:                               << 
1364         mnt_drop_write_file(filp);            << 
1365         return ret;                           << 
1366 }                                             << 
1367                                               << 
1368 long nilfs_ioctl(struct file *filp, unsigned     1295 long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1369 {                                                1296 {
1370         struct inode *inode = file_inode(filp    1297         struct inode *inode = file_inode(filp);
1371         void __user *argp = (void __user *)ar    1298         void __user *argp = (void __user *)arg;
1372                                                  1299 
1373         switch (cmd) {                           1300         switch (cmd) {
                                                   >> 1301         case FS_IOC_GETFLAGS:
                                                   >> 1302                 return nilfs_ioctl_getflags(inode, argp);
                                                   >> 1303         case FS_IOC_SETFLAGS:
                                                   >> 1304                 return nilfs_ioctl_setflags(inode, filp, argp);
1374         case FS_IOC_GETVERSION:                  1305         case FS_IOC_GETVERSION:
1375                 return nilfs_ioctl_getversion    1306                 return nilfs_ioctl_getversion(inode, argp);
1376         case NILFS_IOCTL_CHANGE_CPMODE:          1307         case NILFS_IOCTL_CHANGE_CPMODE:
1377                 return nilfs_ioctl_change_cpm    1308                 return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
1378         case NILFS_IOCTL_DELETE_CHECKPOINT:      1309         case NILFS_IOCTL_DELETE_CHECKPOINT:
1379                 return nilfs_ioctl_delete_che    1310                 return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
1380         case NILFS_IOCTL_GET_CPINFO:             1311         case NILFS_IOCTL_GET_CPINFO:
1381                 return nilfs_ioctl_get_info(i    1312                 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1382                                             s    1313                                             sizeof(struct nilfs_cpinfo),
1383                                             n    1314                                             nilfs_ioctl_do_get_cpinfo);
1384         case NILFS_IOCTL_GET_CPSTAT:             1315         case NILFS_IOCTL_GET_CPSTAT:
1385                 return nilfs_ioctl_get_cpstat    1316                 return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
1386         case NILFS_IOCTL_GET_SUINFO:             1317         case NILFS_IOCTL_GET_SUINFO:
1387                 return nilfs_ioctl_get_info(i    1318                 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1388                                             s    1319                                             sizeof(struct nilfs_suinfo),
1389                                             n    1320                                             nilfs_ioctl_do_get_suinfo);
1390         case NILFS_IOCTL_SET_SUINFO:             1321         case NILFS_IOCTL_SET_SUINFO:
1391                 return nilfs_ioctl_set_suinfo    1322                 return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
1392         case NILFS_IOCTL_GET_SUSTAT:             1323         case NILFS_IOCTL_GET_SUSTAT:
1393                 return nilfs_ioctl_get_sustat    1324                 return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
1394         case NILFS_IOCTL_GET_VINFO:              1325         case NILFS_IOCTL_GET_VINFO:
1395                 return nilfs_ioctl_get_info(i    1326                 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1396                                             s    1327                                             sizeof(struct nilfs_vinfo),
1397                                             n    1328                                             nilfs_ioctl_do_get_vinfo);
1398         case NILFS_IOCTL_GET_BDESCS:             1329         case NILFS_IOCTL_GET_BDESCS:
1399                 return nilfs_ioctl_get_bdescs    1330                 return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
1400         case NILFS_IOCTL_CLEAN_SEGMENTS:         1331         case NILFS_IOCTL_CLEAN_SEGMENTS:
1401                 return nilfs_ioctl_clean_segm    1332                 return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
1402         case NILFS_IOCTL_SYNC:                   1333         case NILFS_IOCTL_SYNC:
1403                 return nilfs_ioctl_sync(inode    1334                 return nilfs_ioctl_sync(inode, filp, cmd, argp);
1404         case NILFS_IOCTL_RESIZE:                 1335         case NILFS_IOCTL_RESIZE:
1405                 return nilfs_ioctl_resize(ino    1336                 return nilfs_ioctl_resize(inode, filp, argp);
1406         case NILFS_IOCTL_SET_ALLOC_RANGE:        1337         case NILFS_IOCTL_SET_ALLOC_RANGE:
1407                 return nilfs_ioctl_set_alloc_    1338                 return nilfs_ioctl_set_alloc_range(inode, argp);
1408         case FITRIM:                             1339         case FITRIM:
1409                 return nilfs_ioctl_trim_fs(in    1340                 return nilfs_ioctl_trim_fs(inode, argp);
1410         case FS_IOC_GETFSLABEL:               << 
1411                 return nilfs_ioctl_get_fslabe << 
1412         case FS_IOC_SETFSLABEL:               << 
1413                 return nilfs_ioctl_set_fslabe << 
1414         default:                                 1341         default:
1415                 return -ENOTTY;                  1342                 return -ENOTTY;
1416         }                                        1343         }
1417 }                                                1344 }
1418                                                  1345 
1419 #ifdef CONFIG_COMPAT                             1346 #ifdef CONFIG_COMPAT
1420 long nilfs_compat_ioctl(struct file *filp, un    1347 long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1421 {                                                1348 {
1422         switch (cmd) {                           1349         switch (cmd) {
                                                   >> 1350         case FS_IOC32_GETFLAGS:
                                                   >> 1351                 cmd = FS_IOC_GETFLAGS;
                                                   >> 1352                 break;
                                                   >> 1353         case FS_IOC32_SETFLAGS:
                                                   >> 1354                 cmd = FS_IOC_SETFLAGS;
                                                   >> 1355                 break;
1423         case FS_IOC32_GETVERSION:                1356         case FS_IOC32_GETVERSION:
1424                 cmd = FS_IOC_GETVERSION;         1357                 cmd = FS_IOC_GETVERSION;
1425                 break;                           1358                 break;
1426         case NILFS_IOCTL_CHANGE_CPMODE:          1359         case NILFS_IOCTL_CHANGE_CPMODE:
1427         case NILFS_IOCTL_DELETE_CHECKPOINT:      1360         case NILFS_IOCTL_DELETE_CHECKPOINT:
1428         case NILFS_IOCTL_GET_CPINFO:             1361         case NILFS_IOCTL_GET_CPINFO:
1429         case NILFS_IOCTL_GET_CPSTAT:             1362         case NILFS_IOCTL_GET_CPSTAT:
1430         case NILFS_IOCTL_GET_SUINFO:             1363         case NILFS_IOCTL_GET_SUINFO:
1431         case NILFS_IOCTL_SET_SUINFO:             1364         case NILFS_IOCTL_SET_SUINFO:
1432         case NILFS_IOCTL_GET_SUSTAT:             1365         case NILFS_IOCTL_GET_SUSTAT:
1433         case NILFS_IOCTL_GET_VINFO:              1366         case NILFS_IOCTL_GET_VINFO:
1434         case NILFS_IOCTL_GET_BDESCS:             1367         case NILFS_IOCTL_GET_BDESCS:
1435         case NILFS_IOCTL_CLEAN_SEGMENTS:         1368         case NILFS_IOCTL_CLEAN_SEGMENTS:
1436         case NILFS_IOCTL_SYNC:                   1369         case NILFS_IOCTL_SYNC:
1437         case NILFS_IOCTL_RESIZE:                 1370         case NILFS_IOCTL_RESIZE:
1438         case NILFS_IOCTL_SET_ALLOC_RANGE:        1371         case NILFS_IOCTL_SET_ALLOC_RANGE:
1439         case FITRIM:                          << 
1440         case FS_IOC_GETFSLABEL:               << 
1441         case FS_IOC_SETFSLABEL:               << 
1442                 break;                           1372                 break;
1443         default:                                 1373         default:
1444                 return -ENOIOCTLCMD;             1374                 return -ENOIOCTLCMD;
1445         }                                        1375         }
1446         return nilfs_ioctl(filp, cmd, (unsign    1376         return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
1447 }                                                1377 }
1448 #endif                                           1378 #endif
1449                                                  1379 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php