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

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

Version: ~ [ linux-5.6 ] ~ [ linux-5.5.13 ] ~ [ linux-5.4.28 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.113 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.174 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.217 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.217 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * linux/fs/ocfs2/ioctl.c
  4  *
  5  * Copyright (C) 2006 Herbert Poetzl
  6  * adapted from Remy Card's ext2/ioctl.c
  7  */
  8 
  9 #include <linux/fs.h>
 10 #include <linux/mount.h>
 11 #include <linux/blkdev.h>
 12 #include <linux/compat.h>
 13 
 14 #include <cluster/masklog.h>
 15 
 16 #include "ocfs2.h"
 17 #include "alloc.h"
 18 #include "dlmglue.h"
 19 #include "file.h"
 20 #include "inode.h"
 21 #include "journal.h"
 22 
 23 #include "ocfs2_fs.h"
 24 #include "ioctl.h"
 25 #include "resize.h"
 26 #include "refcounttree.h"
 27 #include "sysfile.h"
 28 #include "dir.h"
 29 #include "buffer_head_io.h"
 30 #include "suballoc.h"
 31 #include "move_extents.h"
 32 
 33 #define o2info_from_user(a, b)  \
 34                 copy_from_user(&(a), (b), sizeof(a))
 35 #define o2info_to_user(a, b)    \
 36                 copy_to_user((typeof(a) __user *)b, &(a), sizeof(a))
 37 
 38 /*
 39  * This is just a best-effort to tell userspace that this request
 40  * caused the error.
 41  */
 42 static inline void o2info_set_request_error(struct ocfs2_info_request *kreq,
 43                                         struct ocfs2_info_request __user *req)
 44 {
 45         kreq->ir_flags |= OCFS2_INFO_FL_ERROR;
 46         (void)put_user(kreq->ir_flags, (__u32 __user *)&(req->ir_flags));
 47 }
 48 
 49 static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
 50 {
 51         req->ir_flags |= OCFS2_INFO_FL_FILLED;
 52 }
 53 
 54 static inline void o2info_clear_request_filled(struct ocfs2_info_request *req)
 55 {
 56         req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
 57 }
 58 
 59 static inline int o2info_coherent(struct ocfs2_info_request *req)
 60 {
 61         return (!(req->ir_flags & OCFS2_INFO_FL_NON_COHERENT));
 62 }
 63 
 64 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 65 {
 66         int status;
 67 
 68         status = ocfs2_inode_lock(inode, NULL, 0);
 69         if (status < 0) {
 70                 mlog_errno(status);
 71                 return status;
 72         }
 73         ocfs2_get_inode_flags(OCFS2_I(inode));
 74         *flags = OCFS2_I(inode)->ip_attr;
 75         ocfs2_inode_unlock(inode, 0);
 76 
 77         return status;
 78 }
 79 
 80 static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
 81                                 unsigned mask)
 82 {
 83         struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
 84         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 85         handle_t *handle = NULL;
 86         struct buffer_head *bh = NULL;
 87         unsigned oldflags;
 88         int status;
 89 
 90         inode_lock(inode);
 91 
 92         status = ocfs2_inode_lock(inode, &bh, 1);
 93         if (status < 0) {
 94                 mlog_errno(status);
 95                 goto bail;
 96         }
 97 
 98         status = -EACCES;
 99         if (!inode_owner_or_capable(inode))
100                 goto bail_unlock;
101 
102         if (!S_ISDIR(inode->i_mode))
103                 flags &= ~OCFS2_DIRSYNC_FL;
104 
105         oldflags = ocfs2_inode->ip_attr;
106         flags = flags & mask;
107         flags |= oldflags & ~mask;
108 
109         /*
110          * The IMMUTABLE and APPEND_ONLY flags can only be changed by
111          * the relevant capability.
112          */
113         status = -EPERM;
114         if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
115                 (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
116                 if (!capable(CAP_LINUX_IMMUTABLE))
117                         goto bail_unlock;
118         }
119 
120         handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
121         if (IS_ERR(handle)) {
122                 status = PTR_ERR(handle);
123                 mlog_errno(status);
124                 goto bail_unlock;
125         }
126 
127         ocfs2_inode->ip_attr = flags;
128         ocfs2_set_inode_flags(inode);
129 
130         status = ocfs2_mark_inode_dirty(handle, inode, bh);
131         if (status < 0)
132                 mlog_errno(status);
133 
134         ocfs2_commit_trans(osb, handle);
135 
136 bail_unlock:
137         ocfs2_inode_unlock(inode, 1);
138 bail:
139         inode_unlock(inode);
140 
141         brelse(bh);
142 
143         return status;
144 }
145 
146 static int ocfs2_info_handle_blocksize(struct inode *inode,
147                                        struct ocfs2_info_request __user *req)
148 {
149         struct ocfs2_info_blocksize oib;
150 
151         if (o2info_from_user(oib, req))
152                 return -EFAULT;
153 
154         oib.ib_blocksize = inode->i_sb->s_blocksize;
155 
156         o2info_set_request_filled(&oib.ib_req);
157 
158         if (o2info_to_user(oib, req))
159                 return -EFAULT;
160 
161         return 0;
162 }
163 
164 static int ocfs2_info_handle_clustersize(struct inode *inode,
165                                          struct ocfs2_info_request __user *req)
166 {
167         struct ocfs2_info_clustersize oic;
168         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
169 
170         if (o2info_from_user(oic, req))
171                 return -EFAULT;
172 
173         oic.ic_clustersize = osb->s_clustersize;
174 
175         o2info_set_request_filled(&oic.ic_req);
176 
177         if (o2info_to_user(oic, req))
178                 return -EFAULT;
179 
180         return 0;
181 }
182 
183 static int ocfs2_info_handle_maxslots(struct inode *inode,
184                                       struct ocfs2_info_request __user *req)
185 {
186         struct ocfs2_info_maxslots oim;
187         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
188 
189         if (o2info_from_user(oim, req))
190                 return -EFAULT;
191 
192         oim.im_max_slots = osb->max_slots;
193 
194         o2info_set_request_filled(&oim.im_req);
195 
196         if (o2info_to_user(oim, req))
197                 return -EFAULT;
198 
199         return 0;
200 }
201 
202 static int ocfs2_info_handle_label(struct inode *inode,
203                                    struct ocfs2_info_request __user *req)
204 {
205         struct ocfs2_info_label oil;
206         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
207 
208         if (o2info_from_user(oil, req))
209                 return -EFAULT;
210 
211         memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
212 
213         o2info_set_request_filled(&oil.il_req);
214 
215         if (o2info_to_user(oil, req))
216                 return -EFAULT;
217 
218         return 0;
219 }
220 
221 static int ocfs2_info_handle_uuid(struct inode *inode,
222                                   struct ocfs2_info_request __user *req)
223 {
224         struct ocfs2_info_uuid oiu;
225         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
226 
227         if (o2info_from_user(oiu, req))
228                 return -EFAULT;
229 
230         memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
231 
232         o2info_set_request_filled(&oiu.iu_req);
233 
234         if (o2info_to_user(oiu, req))
235                 return -EFAULT;
236 
237         return 0;
238 }
239 
240 static int ocfs2_info_handle_fs_features(struct inode *inode,
241                                          struct ocfs2_info_request __user *req)
242 {
243         struct ocfs2_info_fs_features oif;
244         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
245 
246         if (o2info_from_user(oif, req))
247                 return -EFAULT;
248 
249         oif.if_compat_features = osb->s_feature_compat;
250         oif.if_incompat_features = osb->s_feature_incompat;
251         oif.if_ro_compat_features = osb->s_feature_ro_compat;
252 
253         o2info_set_request_filled(&oif.if_req);
254 
255         if (o2info_to_user(oif, req))
256                 return -EFAULT;
257 
258         return 0;
259 }
260 
261 static int ocfs2_info_handle_journal_size(struct inode *inode,
262                                           struct ocfs2_info_request __user *req)
263 {
264         struct ocfs2_info_journal_size oij;
265         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
266 
267         if (o2info_from_user(oij, req))
268                 return -EFAULT;
269 
270         oij.ij_journal_size = i_size_read(osb->journal->j_inode);
271 
272         o2info_set_request_filled(&oij.ij_req);
273 
274         if (o2info_to_user(oij, req))
275                 return -EFAULT;
276 
277         return 0;
278 }
279 
280 static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb,
281                                        struct inode *inode_alloc, u64 blkno,
282                                        struct ocfs2_info_freeinode *fi,
283                                        u32 slot)
284 {
285         int status = 0, unlock = 0;
286 
287         struct buffer_head *bh = NULL;
288         struct ocfs2_dinode *dinode_alloc = NULL;
289 
290         if (inode_alloc)
291                 inode_lock(inode_alloc);
292 
293         if (o2info_coherent(&fi->ifi_req)) {
294                 status = ocfs2_inode_lock(inode_alloc, &bh, 0);
295                 if (status < 0) {
296                         mlog_errno(status);
297                         goto bail;
298                 }
299                 unlock = 1;
300         } else {
301                 status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
302                 if (status < 0) {
303                         mlog_errno(status);
304                         goto bail;
305                 }
306         }
307 
308         dinode_alloc = (struct ocfs2_dinode *)bh->b_data;
309 
310         fi->ifi_stat[slot].lfi_total =
311                 le32_to_cpu(dinode_alloc->id1.bitmap1.i_total);
312         fi->ifi_stat[slot].lfi_free =
313                 le32_to_cpu(dinode_alloc->id1.bitmap1.i_total) -
314                 le32_to_cpu(dinode_alloc->id1.bitmap1.i_used);
315 
316 bail:
317         if (unlock)
318                 ocfs2_inode_unlock(inode_alloc, 0);
319 
320         if (inode_alloc)
321                 inode_unlock(inode_alloc);
322 
323         brelse(bh);
324 
325         return status;
326 }
327 
328 static int ocfs2_info_handle_freeinode(struct inode *inode,
329                                        struct ocfs2_info_request __user *req)
330 {
331         u32 i;
332         u64 blkno = -1;
333         char namebuf[40];
334         int status, type = INODE_ALLOC_SYSTEM_INODE;
335         struct ocfs2_info_freeinode *oifi = NULL;
336         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
337         struct inode *inode_alloc = NULL;
338 
339         oifi = kzalloc(sizeof(struct ocfs2_info_freeinode), GFP_KERNEL);
340         if (!oifi) {
341                 status = -ENOMEM;
342                 mlog_errno(status);
343                 goto out_err;
344         }
345 
346         if (o2info_from_user(*oifi, req)) {
347                 status = -EFAULT;
348                 goto out_free;
349         }
350 
351         oifi->ifi_slotnum = osb->max_slots;
352 
353         for (i = 0; i < oifi->ifi_slotnum; i++) {
354                 if (o2info_coherent(&oifi->ifi_req)) {
355                         inode_alloc = ocfs2_get_system_file_inode(osb, type, i);
356                         if (!inode_alloc) {
357                                 mlog(ML_ERROR, "unable to get alloc inode in "
358                                     "slot %u\n", i);
359                                 status = -EIO;
360                                 goto bail;
361                         }
362                 } else {
363                         ocfs2_sprintf_system_inode_name(namebuf,
364                                                         sizeof(namebuf),
365                                                         type, i);
366                         status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
367                                                             namebuf,
368                                                             strlen(namebuf),
369                                                             &blkno);
370                         if (status < 0) {
371                                 status = -ENOENT;
372                                 goto bail;
373                         }
374                 }
375 
376                 status = ocfs2_info_scan_inode_alloc(osb, inode_alloc, blkno, oifi, i);
377 
378                 iput(inode_alloc);
379                 inode_alloc = NULL;
380 
381                 if (status < 0)
382                         goto bail;
383         }
384 
385         o2info_set_request_filled(&oifi->ifi_req);
386 
387         if (o2info_to_user(*oifi, req)) {
388                 status = -EFAULT;
389                 goto out_free;
390         }
391 
392         status = 0;
393 bail:
394         if (status)
395                 o2info_set_request_error(&oifi->ifi_req, req);
396 out_free:
397         kfree(oifi);
398 out_err:
399         return status;
400 }
401 
402 static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist,
403                                    unsigned int chunksize)
404 {
405         u32 index;
406 
407         index = __ilog2_u32(chunksize);
408         if (index >= OCFS2_INFO_MAX_HIST)
409                 index = OCFS2_INFO_MAX_HIST - 1;
410 
411         hist->fc_chunks[index]++;
412         hist->fc_clusters[index] += chunksize;
413 }
414 
415 static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats,
416                                unsigned int chunksize)
417 {
418         if (chunksize > stats->ffs_max)
419                 stats->ffs_max = chunksize;
420 
421         if (chunksize < stats->ffs_min)
422                 stats->ffs_min = chunksize;
423 
424         stats->ffs_avg += chunksize;
425         stats->ffs_free_chunks_real++;
426 }
427 
428 static void ocfs2_info_update_ffg(struct ocfs2_info_freefrag *ffg,
429                                   unsigned int chunksize)
430 {
431         o2ffg_update_histogram(&(ffg->iff_ffs.ffs_fc_hist), chunksize);
432         o2ffg_update_stats(&(ffg->iff_ffs), chunksize);
433 }
434 
435 static int ocfs2_info_freefrag_scan_chain(struct ocfs2_super *osb,
436                                           struct inode *gb_inode,
437                                           struct ocfs2_dinode *gb_dinode,
438                                           struct ocfs2_chain_rec *rec,
439                                           struct ocfs2_info_freefrag *ffg,
440                                           u32 chunks_in_group)
441 {
442         int status = 0, used;
443         u64 blkno;
444 
445         struct buffer_head *bh = NULL;
446         struct ocfs2_group_desc *bg = NULL;
447 
448         unsigned int max_bits, num_clusters;
449         unsigned int offset = 0, cluster, chunk;
450         unsigned int chunk_free, last_chunksize = 0;
451 
452         if (!le32_to_cpu(rec->c_free))
453                 goto bail;
454 
455         do {
456                 if (!bg)
457                         blkno = le64_to_cpu(rec->c_blkno);
458                 else
459                         blkno = le64_to_cpu(bg->bg_next_group);
460 
461                 if (bh) {
462                         brelse(bh);
463                         bh = NULL;
464                 }
465 
466                 if (o2info_coherent(&ffg->iff_req))
467                         status = ocfs2_read_group_descriptor(gb_inode,
468                                                              gb_dinode,
469                                                              blkno, &bh);
470                 else
471                         status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
472 
473                 if (status < 0) {
474                         mlog(ML_ERROR, "Can't read the group descriptor # "
475                              "%llu from device.", (unsigned long long)blkno);
476                         status = -EIO;
477                         goto bail;
478                 }
479 
480                 bg = (struct ocfs2_group_desc *)bh->b_data;
481 
482                 if (!le16_to_cpu(bg->bg_free_bits_count))
483                         continue;
484 
485                 max_bits = le16_to_cpu(bg->bg_bits);
486                 offset = 0;
487 
488                 for (chunk = 0; chunk < chunks_in_group; chunk++) {
489                         /*
490                          * last chunk may be not an entire one.
491                          */
492                         if ((offset + ffg->iff_chunksize) > max_bits)
493                                 num_clusters = max_bits - offset;
494                         else
495                                 num_clusters = ffg->iff_chunksize;
496 
497                         chunk_free = 0;
498                         for (cluster = 0; cluster < num_clusters; cluster++) {
499                                 used = ocfs2_test_bit(offset,
500                                                 (unsigned long *)bg->bg_bitmap);
501                                 /*
502                                  * - chunk_free counts free clusters in #N chunk.
503                                  * - last_chunksize records the size(in) clusters
504                                  *   for the last real free chunk being counted.
505                                  */
506                                 if (!used) {
507                                         last_chunksize++;
508                                         chunk_free++;
509                                 }
510 
511                                 if (used && last_chunksize) {
512                                         ocfs2_info_update_ffg(ffg,
513                                                               last_chunksize);
514                                         last_chunksize = 0;
515                                 }
516 
517                                 offset++;
518                         }
519 
520                         if (chunk_free == ffg->iff_chunksize)
521                                 ffg->iff_ffs.ffs_free_chunks++;
522                 }
523 
524                 /*
525                  * need to update the info for last free chunk.
526                  */
527                 if (last_chunksize)
528                         ocfs2_info_update_ffg(ffg, last_chunksize);
529 
530         } while (le64_to_cpu(bg->bg_next_group));
531 
532 bail:
533         brelse(bh);
534 
535         return status;
536 }
537 
538 static int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
539                                            struct inode *gb_inode, u64 blkno,
540                                            struct ocfs2_info_freefrag *ffg)
541 {
542         u32 chunks_in_group;
543         int status = 0, unlock = 0, i;
544 
545         struct buffer_head *bh = NULL;
546         struct ocfs2_chain_list *cl = NULL;
547         struct ocfs2_chain_rec *rec = NULL;
548         struct ocfs2_dinode *gb_dinode = NULL;
549 
550         if (gb_inode)
551                 inode_lock(gb_inode);
552 
553         if (o2info_coherent(&ffg->iff_req)) {
554                 status = ocfs2_inode_lock(gb_inode, &bh, 0);
555                 if (status < 0) {
556                         mlog_errno(status);
557                         goto bail;
558                 }
559                 unlock = 1;
560         } else {
561                 status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
562                 if (status < 0) {
563                         mlog_errno(status);
564                         goto bail;
565                 }
566         }
567 
568         gb_dinode = (struct ocfs2_dinode *)bh->b_data;
569         cl = &(gb_dinode->id2.i_chain);
570 
571         /*
572          * Chunksize(in) clusters from userspace should be
573          * less than clusters in a group.
574          */
575         if (ffg->iff_chunksize > le16_to_cpu(cl->cl_cpg)) {
576                 status = -EINVAL;
577                 goto bail;
578         }
579 
580         memset(&ffg->iff_ffs, 0, sizeof(struct ocfs2_info_freefrag_stats));
581 
582         ffg->iff_ffs.ffs_min = ~0U;
583         ffg->iff_ffs.ffs_clusters =
584                         le32_to_cpu(gb_dinode->id1.bitmap1.i_total);
585         ffg->iff_ffs.ffs_free_clusters = ffg->iff_ffs.ffs_clusters -
586                         le32_to_cpu(gb_dinode->id1.bitmap1.i_used);
587 
588         chunks_in_group = le16_to_cpu(cl->cl_cpg) / ffg->iff_chunksize + 1;
589 
590         for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) {
591                 rec = &(cl->cl_recs[i]);
592                 status = ocfs2_info_freefrag_scan_chain(osb, gb_inode,
593                                                         gb_dinode,
594                                                         rec, ffg,
595                                                         chunks_in_group);
596                 if (status)
597                         goto bail;
598         }
599 
600         if (ffg->iff_ffs.ffs_free_chunks_real)
601                 ffg->iff_ffs.ffs_avg = (ffg->iff_ffs.ffs_avg /
602                                         ffg->iff_ffs.ffs_free_chunks_real);
603 bail:
604         if (unlock)
605                 ocfs2_inode_unlock(gb_inode, 0);
606 
607         if (gb_inode)
608                 inode_unlock(gb_inode);
609 
610         iput(gb_inode);
611         brelse(bh);
612 
613         return status;
614 }
615 
616 static int ocfs2_info_handle_freefrag(struct inode *inode,
617                                       struct ocfs2_info_request __user *req)
618 {
619         u64 blkno = -1;
620         char namebuf[40];
621         int status, type = GLOBAL_BITMAP_SYSTEM_INODE;
622 
623         struct ocfs2_info_freefrag *oiff;
624         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
625         struct inode *gb_inode = NULL;
626 
627         oiff = kzalloc(sizeof(struct ocfs2_info_freefrag), GFP_KERNEL);
628         if (!oiff) {
629                 status = -ENOMEM;
630                 mlog_errno(status);
631                 goto out_err;
632         }
633 
634         if (o2info_from_user(*oiff, req)) {
635                 status = -EFAULT;
636                 goto out_free;
637         }
638         /*
639          * chunksize from userspace should be power of 2.
640          */
641         if ((oiff->iff_chunksize & (oiff->iff_chunksize - 1)) ||
642             (!oiff->iff_chunksize)) {
643                 status = -EINVAL;
644                 goto bail;
645         }
646 
647         if (o2info_coherent(&oiff->iff_req)) {
648                 gb_inode = ocfs2_get_system_file_inode(osb, type,
649                                                        OCFS2_INVALID_SLOT);
650                 if (!gb_inode) {
651                         mlog(ML_ERROR, "unable to get global_bitmap inode\n");
652                         status = -EIO;
653                         goto bail;
654                 }
655         } else {
656                 ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type,
657                                                 OCFS2_INVALID_SLOT);
658                 status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
659                                                     namebuf,
660                                                     strlen(namebuf),
661                                                     &blkno);
662                 if (status < 0) {
663                         status = -ENOENT;
664                         goto bail;
665                 }
666         }
667 
668         status = ocfs2_info_freefrag_scan_bitmap(osb, gb_inode, blkno, oiff);
669         if (status < 0)
670                 goto bail;
671 
672         o2info_set_request_filled(&oiff->iff_req);
673 
674         if (o2info_to_user(*oiff, req)) {
675                 status = -EFAULT;
676                 goto out_free;
677         }
678 
679         status = 0;
680 bail:
681         if (status)
682                 o2info_set_request_error(&oiff->iff_req, req);
683 out_free:
684         kfree(oiff);
685 out_err:
686         return status;
687 }
688 
689 static int ocfs2_info_handle_unknown(struct inode *inode,
690                                      struct ocfs2_info_request __user *req)
691 {
692         struct ocfs2_info_request oir;
693 
694         if (o2info_from_user(oir, req))
695                 return -EFAULT;
696 
697         o2info_clear_request_filled(&oir);
698 
699         if (o2info_to_user(oir, req))
700                 return -EFAULT;
701 
702         return 0;
703 }
704 
705 /*
706  * Validate and distinguish OCFS2_IOC_INFO requests.
707  *
708  * - validate the magic number.
709  * - distinguish different requests.
710  * - validate size of different requests.
711  */
712 static int ocfs2_info_handle_request(struct inode *inode,
713                                      struct ocfs2_info_request __user *req)
714 {
715         int status = -EFAULT;
716         struct ocfs2_info_request oir;
717 
718         if (o2info_from_user(oir, req))
719                 goto bail;
720 
721         status = -EINVAL;
722         if (oir.ir_magic != OCFS2_INFO_MAGIC)
723                 goto bail;
724 
725         switch (oir.ir_code) {
726         case OCFS2_INFO_BLOCKSIZE:
727                 if (oir.ir_size == sizeof(struct ocfs2_info_blocksize))
728                         status = ocfs2_info_handle_blocksize(inode, req);
729                 break;
730         case OCFS2_INFO_CLUSTERSIZE:
731                 if (oir.ir_size == sizeof(struct ocfs2_info_clustersize))
732                         status = ocfs2_info_handle_clustersize(inode, req);
733                 break;
734         case OCFS2_INFO_MAXSLOTS:
735                 if (oir.ir_size == sizeof(struct ocfs2_info_maxslots))
736                         status = ocfs2_info_handle_maxslots(inode, req);
737                 break;
738         case OCFS2_INFO_LABEL:
739                 if (oir.ir_size == sizeof(struct ocfs2_info_label))
740                         status = ocfs2_info_handle_label(inode, req);
741                 break;
742         case OCFS2_INFO_UUID:
743                 if (oir.ir_size == sizeof(struct ocfs2_info_uuid))
744                         status = ocfs2_info_handle_uuid(inode, req);
745                 break;
746         case OCFS2_INFO_FS_FEATURES:
747                 if (oir.ir_size == sizeof(struct ocfs2_info_fs_features))
748                         status = ocfs2_info_handle_fs_features(inode, req);
749                 break;
750         case OCFS2_INFO_JOURNAL_SIZE:
751                 if (oir.ir_size == sizeof(struct ocfs2_info_journal_size))
752                         status = ocfs2_info_handle_journal_size(inode, req);
753                 break;
754         case OCFS2_INFO_FREEINODE:
755                 if (oir.ir_size == sizeof(struct ocfs2_info_freeinode))
756                         status = ocfs2_info_handle_freeinode(inode, req);
757                 break;
758         case OCFS2_INFO_FREEFRAG:
759                 if (oir.ir_size == sizeof(struct ocfs2_info_freefrag))
760                         status = ocfs2_info_handle_freefrag(inode, req);
761                 break;
762         default:
763                 status = ocfs2_info_handle_unknown(inode, req);
764                 break;
765         }
766 
767 bail:
768         return status;
769 }
770 
771 static int ocfs2_get_request_ptr(struct ocfs2_info *info, int idx,
772                                  u64 *req_addr, int compat_flag)
773 {
774         int status = -EFAULT;
775         u64 __user *bp = NULL;
776 
777         if (compat_flag) {
778 #ifdef CONFIG_COMPAT
779                 /*
780                  * pointer bp stores the base address of a pointers array,
781                  * which collects all addresses of separate request.
782                  */
783                 bp = (u64 __user *)(unsigned long)compat_ptr(info->oi_requests);
784 #else
785                 BUG();
786 #endif
787         } else
788                 bp = (u64 __user *)(unsigned long)(info->oi_requests);
789 
790         if (o2info_from_user(*req_addr, bp + idx))
791                 goto bail;
792 
793         status = 0;
794 bail:
795         return status;
796 }
797 
798 /*
799  * OCFS2_IOC_INFO handles an array of requests passed from userspace.
800  *
801  * ocfs2_info_handle() recevies a large info aggregation, grab and
802  * validate the request count from header, then break it into small
803  * pieces, later specific handlers can handle them one by one.
804  *
805  * Idea here is to make each separate request small enough to ensure
806  * a better backward&forward compatibility, since a small piece of
807  * request will be less likely to be broken if disk layout get changed.
808  */
809 static int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info,
810                              int compat_flag)
811 {
812         int i, status = 0;
813         u64 req_addr;
814         struct ocfs2_info_request __user *reqp;
815 
816         if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) ||
817             (!info->oi_requests)) {
818                 status = -EINVAL;
819                 goto bail;
820         }
821 
822         for (i = 0; i < info->oi_count; i++) {
823 
824                 status = ocfs2_get_request_ptr(info, i, &req_addr, compat_flag);
825                 if (status)
826                         break;
827 
828                 reqp = (struct ocfs2_info_request __user *)(unsigned long)req_addr;
829                 if (!reqp) {
830                         status = -EINVAL;
831                         goto bail;
832                 }
833 
834                 status = ocfs2_info_handle_request(inode, reqp);
835                 if (status)
836                         break;
837         }
838 
839 bail:
840         return status;
841 }
842 
843 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
844 {
845         struct inode *inode = file_inode(filp);
846         unsigned int flags;
847         int new_clusters;
848         int status;
849         struct ocfs2_space_resv sr;
850         struct ocfs2_new_group_input input;
851         struct reflink_arguments args;
852         const char __user *old_path;
853         const char __user *new_path;
854         bool preserve;
855         struct ocfs2_info info;
856         void __user *argp = (void __user *)arg;
857 
858         switch (cmd) {
859         case OCFS2_IOC_GETFLAGS:
860                 status = ocfs2_get_inode_attr(inode, &flags);
861                 if (status < 0)
862                         return status;
863 
864                 flags &= OCFS2_FL_VISIBLE;
865                 return put_user(flags, (int __user *) arg);
866         case OCFS2_IOC_SETFLAGS:
867                 if (get_user(flags, (int __user *) arg))
868                         return -EFAULT;
869 
870                 status = mnt_want_write_file(filp);
871                 if (status)
872                         return status;
873                 status = ocfs2_set_inode_attr(inode, flags,
874                         OCFS2_FL_MODIFIABLE);
875                 mnt_drop_write_file(filp);
876                 return status;
877         case OCFS2_IOC_RESVSP:
878         case OCFS2_IOC_RESVSP64:
879         case OCFS2_IOC_UNRESVSP:
880         case OCFS2_IOC_UNRESVSP64:
881                 if (copy_from_user(&sr, (int __user *) arg, sizeof(sr)))
882                         return -EFAULT;
883 
884                 return ocfs2_change_file_space(filp, cmd, &sr);
885         case OCFS2_IOC_GROUP_EXTEND:
886                 if (!capable(CAP_SYS_RESOURCE))
887                         return -EPERM;
888 
889                 if (get_user(new_clusters, (int __user *)arg))
890                         return -EFAULT;
891 
892                 status = mnt_want_write_file(filp);
893                 if (status)
894                         return status;
895                 status = ocfs2_group_extend(inode, new_clusters);
896                 mnt_drop_write_file(filp);
897                 return status;
898         case OCFS2_IOC_GROUP_ADD:
899         case OCFS2_IOC_GROUP_ADD64:
900                 if (!capable(CAP_SYS_RESOURCE))
901                         return -EPERM;
902 
903                 if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
904                         return -EFAULT;
905 
906                 status = mnt_want_write_file(filp);
907                 if (status)
908                         return status;
909                 status = ocfs2_group_add(inode, &input);
910                 mnt_drop_write_file(filp);
911                 return status;
912         case OCFS2_IOC_REFLINK:
913                 if (copy_from_user(&args, argp, sizeof(args)))
914                         return -EFAULT;
915                 old_path = (const char __user *)(unsigned long)args.old_path;
916                 new_path = (const char __user *)(unsigned long)args.new_path;
917                 preserve = (args.preserve != 0);
918 
919                 return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve);
920         case OCFS2_IOC_INFO:
921                 if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
922                         return -EFAULT;
923 
924                 return ocfs2_info_handle(inode, &info, 0);
925         case FITRIM:
926         {
927                 struct super_block *sb = inode->i_sb;
928                 struct request_queue *q = bdev_get_queue(sb->s_bdev);
929                 struct fstrim_range range;
930                 int ret = 0;
931 
932                 if (!capable(CAP_SYS_ADMIN))
933                         return -EPERM;
934 
935                 if (!blk_queue_discard(q))
936                         return -EOPNOTSUPP;
937 
938                 if (copy_from_user(&range, argp, sizeof(range)))
939                         return -EFAULT;
940 
941                 range.minlen = max_t(u64, q->limits.discard_granularity,
942                                      range.minlen);
943                 ret = ocfs2_trim_fs(sb, &range);
944                 if (ret < 0)
945                         return ret;
946 
947                 if (copy_to_user(argp, &range, sizeof(range)))
948                         return -EFAULT;
949 
950                 return 0;
951         }
952         case OCFS2_IOC_MOVE_EXT:
953                 return ocfs2_ioctl_move_extents(filp, argp);
954         default:
955                 return -ENOTTY;
956         }
957 }
958 
959 #ifdef CONFIG_COMPAT
960 long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
961 {
962         bool preserve;
963         struct reflink_arguments args;
964         struct inode *inode = file_inode(file);
965         struct ocfs2_info info;
966         void __user *argp = (void __user *)arg;
967 
968         switch (cmd) {
969         case OCFS2_IOC32_GETFLAGS:
970                 cmd = OCFS2_IOC_GETFLAGS;
971                 break;
972         case OCFS2_IOC32_SETFLAGS:
973                 cmd = OCFS2_IOC_SETFLAGS;
974                 break;
975         case OCFS2_IOC_RESVSP:
976         case OCFS2_IOC_RESVSP64:
977         case OCFS2_IOC_UNRESVSP:
978         case OCFS2_IOC_UNRESVSP64:
979         case OCFS2_IOC_GROUP_EXTEND:
980         case OCFS2_IOC_GROUP_ADD:
981         case OCFS2_IOC_GROUP_ADD64:
982                 break;
983         case OCFS2_IOC_REFLINK:
984                 if (copy_from_user(&args, argp, sizeof(args)))
985                         return -EFAULT;
986                 preserve = (args.preserve != 0);
987 
988                 return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
989                                            compat_ptr(args.new_path), preserve);
990         case OCFS2_IOC_INFO:
991                 if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
992                         return -EFAULT;
993 
994                 return ocfs2_info_handle(inode, &info, 1);
995         case OCFS2_IOC_MOVE_EXT:
996                 break;
997         default:
998                 return -ENOIOCTLCMD;
999         }
1000 
1001         return ocfs2_ioctl(file, cmd, arg);
1002 }
1003 #endif
1004 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp