"Fossies" - the Fresh Open Source Software Archive

Member "quotactl-1.00/quotause/quotaio.c" (29 Sep 2005, 6215 Bytes) of package /linux/privat/old/quotactl-1.00.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "quotaio.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *
    3  *  Generic IO operations on quotafiles
    4  *
    5  *  Jan Kara <jack@suse.cz> - sponsored by SuSE CR
    6  */
    7 
    8 #define _GNU_SOURCE
    9 
   10 #include <stdbool.h>
   11 #include <stdio.h>
   12 #include <errno.h>
   13 #include <string.h>
   14 #include <unistd.h>
   15 #include <stdlib.h>
   16 #include <sys/types.h>
   17 #include <sys/stat.h>
   18 #include <sys/file.h>
   19 #include <asm/byteorder.h>
   20 
   21 #include <giraffe/girstring.h>
   22 #include <giraffe/mallocvar.h>
   23 
   24 #include "misc.h"
   25 #include "quotaio.h"
   26 
   27 #include "dqblk_v1.h"
   28 #include "dqblk_v2.h"
   29 #include "dqblk_rpc.h"
   30 
   31 /* Header in all newer quotafiles */
   32 struct disk_dqheader {
   33     u_int32_t dqh_magic;
   34     u_int32_t dqh_version;
   35 } __attribute__ ((packed));
   36 
   37 
   38 
   39 const char * const fmtnamesArray[] = {
   40     [QF_VFSOLD] = "vfsold",
   41     [QF_VFSV0]  = "vfsv0",
   42     [QF_XFS]    = "xfs",
   43 };
   44 
   45 const char * const * const fmtnames = fmtnamesArray;
   46 
   47 
   48 
   49 static void
   50 initializeQuotaFile(struct quota_handle * const quotaFileP,
   51                     int                   const fmt,
   52                     const char **         const errorP) {
   53 
   54     if (fmt == QF_VFSOLD)
   55         quotaFileP->qh_ops = &quotafile_ops_1;
   56     else
   57         quotaFileP->qh_ops = &quotafile_ops_2;
   58     
   59     if (quotaFileP->qh_ops->create_file) {
   60         int rc;
   61         rc =  quotaFileP->qh_ops->create_file(quotaFileP);
   62         if (rc < 0)
   63             casprintf(errorP, "create_file() failed with errno %d (%s)",
   64                       errno, strerror(errno));
   65         else
   66             *errorP = NULL;
   67     } else
   68         *errorP = NULL;
   69 }
   70 
   71 
   72 
   73 static void
   74 determineQuotaFileFormat(int                 const fd,
   75                          int                 const type,
   76                          enum quotaFileFmt * const fmtP,
   77                          const char **       const errorP) {
   78 
   79     bool ok;
   80 
   81     ok = quotafile_ops_2.check_file(fd, type);
   82     if (ok) {
   83         *fmtP = QF_VFSV0;
   84         *errorP = NULL;
   85     } else {
   86         bool ok;
   87         ok = quotafile_ops_1.check_file(fd, type);
   88         
   89         if (ok) {
   90             *fmtP = QF_VFSOLD;
   91             *errorP = NULL;
   92         } else {
   93             casprintf(errorP, "Unrecognized quota file format.  "
   94                       "I recognize only the old format and the new V0 "
   95                       "format.  This file is neither.");
   96         }
   97     }
   98 }
   99 
  100 
  101 
  102 static void
  103 readInitialQuotaFile(struct quota_handle * const quotaFileP,
  104                      const char **         const errorP) {
  105 
  106     determineQuotaFileFormat(quotaFileP->qh_fd, quotaFileP->qh_type,
  107                              &quotaFileP->qh_fmt, errorP);
  108 
  109     if (!*errorP) {
  110         switch(quotaFileP->qh_fmt) {
  111         case QF_VFSOLD:
  112             quotaFileP->qh_ops = &quotafile_ops_1;
  113             break;
  114         case QF_VFSV0:
  115             quotaFileP->qh_ops = &quotafile_ops_2;
  116             break;
  117         default:
  118             casprintf(errorP, "Unrecognized quota file format %d.  "
  119                       "We know %d (old) and %d (new)",
  120                       quotaFileP->qh_fmt, QF_VFSOLD, QF_VFSV0);
  121         }
  122         
  123         if (!*errorP) {
  124             if (quotaFileP->qh_ops->init_read) {
  125                 int rc;
  126                 rc = quotaFileP->qh_ops->init_read(quotaFileP);
  127                 if (rc < 0)
  128                     casprintf(errorP, "init_read() failed.  errno=%d (%s)",
  129                               errno, strerror(errno));
  130             }
  131         }
  132     }
  133 }
  134 
  135 
  136 
  137 void
  138 new_io(enum opentype          const opentype,
  139        const char *           const qfname,
  140        int                    const type,
  141        enum quotaFileFmt      const fmt,
  142        struct quota_handle ** const quotaFilePP,
  143        const char **          const errorP) {
  144 
  145     *errorP = NULL;  /* initial value */
  146 
  147     if (fmt == QF_XFS)
  148         casprintf(errorP, "I don't know how to create XFS quota format.");
  149     else {
  150         int fd;
  151         struct quota_handle * quotaFileP;
  152         int openFlags;
  153 
  154 
  155         switch (opentype) {
  156         case OPEN_NEW: openFlags = O_RDWR | O_CREAT | O_TRUNC; break;
  157         case OPEN_READ: openFlags = O_RDONLY; break;
  158         }
  159         
  160         fd = open(qfname, openFlags, S_IRUSR | S_IWUSR);
  161         if (fd < 0) {
  162             casprintf(errorP, "Can't create new quotafile '%s'.  "
  163                       "errno=%d (%s)",
  164                       qfname, errno, strerror(errno));
  165         } else {
  166             MALLOCVAR_NOFAIL(quotaFileP);
  167 
  168             quotaFileP->qh_fd = fd;
  169             quotaFileP->qh_io_flags = 0;
  170             STRSCPY(quotaFileP->qh_quotadev, "???");
  171             quotaFileP->qh_type = type;
  172             memset(&quotaFileP->qh_info, 0, sizeof(quotaFileP->qh_info));
  173         
  174             flock(fd, LOCK_EX);
  175         
  176             if (opentype == OPEN_NEW) {
  177                 const char * error;
  178                 initializeQuotaFile(quotaFileP, fmt, &error);
  179                 if (error) {
  180                     casprintf(errorP, "Unable to initialize new quota file.  "
  181                               "%s", error);
  182                     strfree(error);
  183                 }
  184             } else if (opentype == OPEN_READ) {
  185                 const char * error;
  186                 readInitialQuotaFile(quotaFileP, &error);
  187                 if (error) {
  188                     casprintf(errorP, "Unable to read header of quota file.  "
  189                               "%s", error);
  190                     strfree(error);
  191                 }
  192             }
  193             
  194             if (*errorP) {
  195                 flock(fd, LOCK_UN);
  196                 free(quotaFileP);
  197                 close(fd);
  198             }
  199         }
  200         *quotaFilePP = quotaFileP;
  201     }
  202 }
  203 
  204 
  205 
  206 /*
  207  *  Close quotafile and release handle
  208  */
  209 int
  210 end_io(struct quota_handle * const h) {
  211 
  212     if (h->qh_io_flags & IOFL_INFODIRTY) {
  213         if (h->qh_ops->write_info && h->qh_ops->write_info(h) < 0)
  214             return -1;
  215         h->qh_io_flags &= ~IOFL_INFODIRTY;
  216     }
  217     if (h->qh_ops->end_io && h->qh_ops->end_io(h) < 0)
  218         return -1;
  219     if (h->qh_fd != -1) {
  220         flock(h->qh_fd, LOCK_UN);
  221         close(h->qh_fd);
  222     }
  223     free(h);
  224 
  225     return 0;
  226 }
  227 
  228 
  229 
  230 /*
  231  *  Create empty quota structure
  232  */
  233 struct dquot *
  234 get_empty_dquot(void) {
  235     struct dquot * dquot;
  236 
  237     MALLOCVAR_NOFAIL(dquot);
  238 
  239     memset(dquot, 0, sizeof(*dquot));
  240     dquot->dq_id = -1;
  241     return dquot;
  242 }