nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 3 of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 * ------------- 00023 */ 00024 00030 #ifdef HAVE_CONFIG_H 00031 #include "config.h" 00032 #endif 00033 00034 #include "fsal.h" 00035 #include "fsal_internal.h" 00036 #include "fsal_convert.h" 00037 00038 /* For quotactl */ 00039 #include <sys/quota.h> 00040 #include <sys/types.h> 00041 #include <string.h> 00042 00060 fsal_status_t XFSFSAL_get_quota(fsal_path_t * pfsal_path, /* IN */ 00061 int quota_type, /* IN */ 00062 fsal_uid_t fsal_uid, /* IN */ 00063 fsal_quota_t * pquota) /* OUT */ 00064 { 00065 struct dqblk fs_quota; 00066 char fs_spec[MAXPATHLEN]; 00067 00068 if(!pfsal_path || !pquota) 00069 ReturnCode(ERR_FSAL_FAULT, 0); 00070 00071 if(fsal_internal_path2fsname(pfsal_path->path, fs_spec) == -1) 00072 ReturnCode(ERR_FSAL_INVAL, 0); 00073 00074 memset((char *)&fs_quota, 0, sizeof(struct dqblk)); 00075 00076 if(quotactl(FSAL_QCMD(Q_GETQUOTA, quota_type), fs_spec, fsal_uid, (caddr_t) & fs_quota) 00077 < 0) 00078 ReturnCode(posix2fsal_error(errno), errno); 00079 00080 /* Convert XFS structure to FSAL one */ 00081 pquota->bhardlimit = fs_quota.dqb_bhardlimit; 00082 pquota->bsoftlimit = fs_quota.dqb_bsoftlimit; 00083 pquota->curblocks = fs_quota.dqb_curspace; 00084 pquota->fhardlimit = fs_quota.dqb_ihardlimit; 00085 pquota->curfiles = fs_quota.dqb_curinodes; 00086 pquota->btimeleft = fs_quota.dqb_btime; 00087 pquota->ftimeleft = fs_quota.dqb_itime; 00088 pquota->bsize = DEV_BSIZE; 00089 00090 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00091 } /* FSAL_get_quota */ 00092 00113 fsal_status_t XFSFSAL_set_quota(fsal_path_t * pfsal_path, /* IN */ 00114 int quota_type, /* IN */ 00115 fsal_uid_t fsal_uid, /* IN */ 00116 fsal_quota_t * pquota, /* IN */ 00117 fsal_quota_t * presquota) /* OUT */ 00118 { 00119 struct dqblk fs_quota; 00120 fsal_status_t fsal_status; 00121 char fs_spec[MAXPATHLEN]; 00122 00123 if(!pfsal_path || !pquota) 00124 ReturnCode(ERR_FSAL_FAULT, 0); 00125 00126 if(fsal_internal_path2fsname(pfsal_path->path, fs_spec) == -1) 00127 ReturnCode(ERR_FSAL_INVAL, 0); 00128 00129 memset((char *)&fs_quota, 0, sizeof(struct dqblk)); 00130 00131 /* Convert FSAL structure to XFS one */ 00132 if(pquota->bhardlimit != 0) 00133 { 00134 fs_quota.dqb_bhardlimit = pquota->bhardlimit; 00135 fs_quota.dqb_valid |= QIF_BLIMITS; 00136 } 00137 00138 if(pquota->bsoftlimit != 0) 00139 { 00140 fs_quota.dqb_bsoftlimit = pquota->bsoftlimit; 00141 fs_quota.dqb_valid |= QIF_BLIMITS; 00142 } 00143 00144 if(pquota->fhardlimit != 0) 00145 { 00146 fs_quota.dqb_ihardlimit = pquota->fhardlimit; 00147 fs_quota.dqb_valid |= QIF_ILIMITS; 00148 } 00149 00150 if(pquota->btimeleft != 0) 00151 { 00152 fs_quota.dqb_btime = pquota->btimeleft; 00153 fs_quota.dqb_valid |= QIF_BTIME; 00154 } 00155 00156 if(pquota->ftimeleft != 0) 00157 { 00158 fs_quota.dqb_itime = pquota->ftimeleft; 00159 fs_quota.dqb_valid |= QIF_ITIME; 00160 } 00161 00162 if(quotactl(FSAL_QCMD(Q_SETQUOTA, quota_type), fs_spec, fsal_uid, (caddr_t) & fs_quota) 00163 < 0) 00164 ReturnCode(posix2fsal_error(errno), errno); 00165 00166 if(presquota != NULL) 00167 { 00168 fsal_status = FSAL_get_quota(pfsal_path, quota_type, fsal_uid, presquota); 00169 00170 if(FSAL_IS_ERROR(fsal_status)) 00171 return fsal_status; 00172 } 00173 00174 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00175 } /* FSAL_set_quota */ 00176 00177 00194 fsal_status_t XFSFSAL_check_quota( char * fs_spec, /* IN */ 00195 fsal_quota_type_t quota_type, 00196 fsal_uid_t fsal_uid) /* IN */ 00197 { 00198 struct dqblk fs_quota; 00199 00200 if(!fs_spec ) 00201 ReturnCode(ERR_FSAL_FAULT, 0); 00202 00203 if( fsal_uid == 0 ) /* No quota for root */ 00204 ReturnCode(ERR_FSAL_NO_ERROR, 0) ; 00205 00206 memset(&fs_quota, 0, sizeof(struct dqblk)); 00207 00208 if(quotactl(FSAL_QCMD(Q_GETQUOTA, USRQUOTA), fs_spec, fsal_uid, (caddr_t) & fs_quota) < 0 ) 00209 ReturnCode(posix2fsal_error(errno), errno); 00210 00211 switch( quota_type ) 00212 { 00213 case FSAL_QUOTA_BLOCKS: 00214 if( fs_quota.dqb_curspace > fs_quota.dqb_bhardlimit ) 00215 ReturnCode( ERR_FSAL_DQUOT, EDQUOT ) ; 00216 00217 break ; 00218 00219 case FSAL_QUOTA_INODES: 00220 if( fs_quota.dqb_curinodes > fs_quota.dqb_ihardlimit ) 00221 ReturnCode( ERR_FSAL_DQUOT, EDQUOT ) ; 00222 00223 break ; 00224 } /* switch( quota_type ) */ 00225 00226 ReturnCode(ERR_FSAL_NO_ERROR, 0) ; 00227 } /* XFSFSAL_check_quota */ 00228