~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/lib/sysquotas_xfs.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
   System QUOTA function wrappers for XFS
 
4
   Copyright (C) Stefan (metze) Metzmacher      2003
 
5
   
 
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 3 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, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
 
 
21
#include "includes.h"
 
22
 
 
23
#undef DBGC_CLASS
 
24
#define DBGC_CLASS DBGC_QUOTA
 
25
 
 
26
#ifndef HAVE_SYS_QUOTAS
 
27
#ifdef HAVE_XFS_QUOTAS
 
28
#undef HAVE_XFS_QUOTAS
 
29
#endif
 
30
#endif
 
31
 
 
32
#ifdef HAVE_XFS_QUOTAS
 
33
 
 
34
#ifdef HAVE_LINUX_XFS_QUOTAS
 
35
#include "samba_linux_quota.h"
 
36
#ifdef HAVE_LINUX_DQBLK_XFS_H
 
37
#include <linux/dqblk_xfs.h>
 
38
#endif
 
39
#define HAVE_GROUP_QUOTA
 
40
#else /* IRIX */
 
41
#include <sys/quota.h> 
 
42
#endif
 
43
 
 
44
/* on IRIX */
 
45
#ifndef Q_XQUOTAON
 
46
#define Q_XQUOTAON Q_QUOTAON
 
47
#endif /* Q_XQUOTAON */
 
48
#ifndef Q_XQUOTAOFF
 
49
#define Q_XQUOTAOFF Q_QUOTAOFF
 
50
#endif /* Q_XQUOTAOFF */
 
51
#ifndef Q_XGETQSTAT
 
52
#define Q_XGETQSTAT Q_GETQSTAT
 
53
#endif /* Q_XGETQSTAT */
 
54
 
 
55
/* currently doesn't support Group and Project quotas on IRIX 
 
56
 */
 
57
 
 
58
#ifndef QCMD
 
59
#define QCMD(x,y) x
 
60
#endif
 
61
 
 
62
/*
 
63
 * IRIX has BBSIZE in <sys/param.h>
 
64
 */
 
65
#ifndef BBSHIFT
 
66
#define BBSHIFT         9
 
67
#endif /* BBSHIFT */
 
68
#ifndef BBSIZE
 
69
#define BBSIZE          (1<<BBSHIFT)
 
70
#endif /* BBSIZE */
 
71
 
 
72
/****************************************************************************
 
73
 Abstract out the XFS Quota Manager quota get call.
 
74
****************************************************************************/
 
75
int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
 
76
{
 
77
        int ret = -1;
 
78
        uint32 qflags = 0;
 
79
        uint64_t bsize = (uint64_t)BBSIZE;
 
80
        struct fs_disk_quota D;
 
81
        struct fs_quota_stat F;
 
82
        ZERO_STRUCT(D);
 
83
        ZERO_STRUCT(F);
 
84
 
 
85
        if (!bdev||!dp)
 
86
                smb_panic("sys_get_xfs_quota: called with NULL pointer");
 
87
                
 
88
        ZERO_STRUCT(*dp);
 
89
        dp->qtype = qtype;
 
90
                
 
91
        switch (qtype) {
 
92
                case SMB_USER_QUOTA_TYPE:
 
93
                        DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
 
94
                                path, bdev, (unsigned)id.uid));
 
95
 
 
96
                        if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D)))
 
97
                                return ret;
 
98
                        break;
 
99
#ifdef HAVE_GROUP_QUOTA
 
100
                case SMB_GROUP_QUOTA_TYPE:
 
101
                        DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
 
102
                                path, bdev, (unsigned)id.gid));
 
103
 
 
104
                        if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D)))
 
105
                                return ret;
 
106
                        break;
 
107
#endif /* HAVE_GROUP_QUOTA */
 
108
                case SMB_USER_FS_QUOTA_TYPE:
 
109
                        DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
 
110
                                path, bdev, (unsigned)id.uid));
 
111
 
 
112
                        quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
 
113
 
 
114
                        if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
 
115
                                qflags |= QUOTAS_DENY_DISK;
 
116
                        }
 
117
                        else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
 
118
                                qflags |= QUOTAS_ENABLED;
 
119
                        }
 
120
 
 
121
                        ret = 0;
 
122
 
 
123
                        break;
 
124
#ifdef HAVE_GROUP_QUOTA
 
125
                case SMB_GROUP_FS_QUOTA_TYPE:
 
126
                        DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
 
127
                                path, bdev, (unsigned)id.gid));
 
128
 
 
129
                        quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
 
130
 
 
131
                        if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
 
132
                                qflags |= QUOTAS_DENY_DISK;
 
133
                        }
 
134
                        else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
 
135
                                qflags |= QUOTAS_ENABLED;
 
136
                        }
 
137
 
 
138
                        ret = 0;
 
139
 
 
140
                        break;
 
141
#endif /* HAVE_GROUP_QUOTA */
 
142
                default:
 
143
                        errno = ENOSYS;
 
144
                        return -1;
 
145
        }
 
146
 
 
147
        dp->bsize = bsize;
 
148
        dp->softlimit = (uint64_t)D.d_blk_softlimit;
 
149
        dp->hardlimit = (uint64_t)D.d_blk_hardlimit;
 
150
        dp->ihardlimit = (uint64_t)D.d_ino_hardlimit;
 
151
        dp->isoftlimit = (uint64_t)D.d_ino_softlimit;
 
152
        dp->curinodes = (uint64_t)D.d_icount;
 
153
        dp->curblocks = (uint64_t)D.d_bcount;
 
154
        dp->qflags = qflags;
 
155
 
 
156
        return ret;
 
157
}
 
158
 
 
159
/****************************************************************************
 
160
 Abstract out the XFS Quota Manager quota set call.
 
161
****************************************************************************/
 
162
int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
 
163
{
 
164
        int ret = -1;
 
165
        uint32 qflags = 0;
 
166
        uint64_t bsize = (uint64_t)BBSIZE;
 
167
        struct fs_disk_quota D;
 
168
        struct fs_quota_stat F;
 
169
        int q_on = 0;
 
170
        int q_off = 0;
 
171
        ZERO_STRUCT(D);
 
172
        ZERO_STRUCT(F);
 
173
 
 
174
        if (!bdev||!dp)
 
175
                smb_panic("sys_set_xfs_quota: called with NULL pointer");
 
176
        
 
177
        if (bsize == dp->bsize) {
 
178
                D.d_blk_softlimit = dp->softlimit;
 
179
                D.d_blk_hardlimit = dp->hardlimit;
 
180
                D.d_ino_hardlimit = dp->ihardlimit;
 
181
                D.d_ino_softlimit = dp->isoftlimit;
 
182
        } else {
 
183
                D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
 
184
                D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
 
185
                D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
 
186
                D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;           
 
187
        }
 
188
 
 
189
        qflags = dp->qflags;
 
190
 
 
191
        switch (qtype) {
 
192
                case SMB_USER_QUOTA_TYPE:
 
193
                        DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
 
194
                                path, bdev, (unsigned)id.uid));
 
195
 
 
196
                        D.d_fieldmask |= FS_DQ_LIMIT_MASK;
 
197
                        ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
 
198
                        break;
 
199
#ifdef HAVE_GROUP_QUOTA
 
200
                case SMB_GROUP_QUOTA_TYPE:
 
201
                        DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
 
202
                                path, bdev, (unsigned)id.gid));
 
203
 
 
204
                        D.d_fieldmask |= FS_DQ_LIMIT_MASK;
 
205
                        ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
 
206
                        break;
 
207
#endif /* HAVE_GROUP_QUOTA */
 
208
                case SMB_USER_FS_QUOTA_TYPE:
 
209
                        DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
 
210
                                path, bdev, (unsigned)id.uid));
 
211
 
 
212
                        quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
 
213
                        
 
214
                        if (qflags & QUOTAS_DENY_DISK) {
 
215
                                if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
 
216
                                        q_on |= XFS_QUOTA_UDQ_ENFD;
 
217
                                if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
 
218
                                        q_on |= XFS_QUOTA_UDQ_ACCT;
 
219
                                
 
220
                                if (q_on != 0) {
 
221
                                        ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
 
222
                                } else {
 
223
                                        ret = 0;
 
224
                                }
 
225
 
 
226
                        } else if (qflags & QUOTAS_ENABLED) {
 
227
                                if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
 
228
                                        q_off |= XFS_QUOTA_UDQ_ENFD;
 
229
 
 
230
                                if (q_off != 0) {
 
231
                                        ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
 
232
                                } else {
 
233
                                        ret = 0;
 
234
                                }
 
235
 
 
236
                                if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
 
237
                                        q_on |= XFS_QUOTA_UDQ_ACCT;
 
238
 
 
239
                                if (q_on != 0) {
 
240
                                        ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
 
241
                                } else {
 
242
                                        ret = 0;
 
243
                                }
 
244
                        } else {
 
245
#if 0
 
246
                        /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
 
247
                         * only swittching off XFS_QUOTA_UDQ_ACCT work
 
248
                         */
 
249
                                if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
 
250
                                        q_off |= XFS_QUOTA_UDQ_ENFD;
 
251
                                if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
 
252
                                        q_off |= XFS_QUOTA_UDQ_ACCT;
 
253
 
 
254
                                if (q_off !=0) {
 
255
                                        ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
 
256
                                } else {
 
257
                                        ret = 0;
 
258
                                }
 
259
#else
 
260
                                ret = -1;
 
261
#endif
 
262
                        }
 
263
 
 
264
                        break;
 
265
#ifdef HAVE_GROUP_QUOTA
 
266
                case SMB_GROUP_FS_QUOTA_TYPE:
 
267
                        DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
 
268
                                path, bdev, (unsigned)id.gid));
 
269
 
 
270
                        quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
 
271
                        
 
272
                        if (qflags & QUOTAS_DENY_DISK) {
 
273
                                if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
 
274
                                        q_on |= XFS_QUOTA_GDQ_ENFD;
 
275
                                if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
 
276
                                        q_on |= XFS_QUOTA_GDQ_ACCT;
 
277
                                
 
278
                                if (q_on != 0) {
 
279
                                        ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
 
280
                                } else {
 
281
                                        ret = 0;
 
282
                                }
 
283
 
 
284
                        } else if (qflags & QUOTAS_ENABLED) {
 
285
                                if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
 
286
                                        q_off |= XFS_QUOTA_GDQ_ENFD;
 
287
 
 
288
                                if (q_off != 0) {
 
289
                                        ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
 
290
                                } else {
 
291
                                        ret = 0;
 
292
                                }
 
293
 
 
294
                                if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
 
295
                                        q_on |= XFS_QUOTA_GDQ_ACCT;
 
296
 
 
297
                                if (q_on != 0) {
 
298
                                        ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
 
299
                                } else {
 
300
                                        ret = 0;
 
301
                                }
 
302
                        } else {
 
303
#if 0
 
304
                        /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
 
305
                         * only swittching off XFS_QUOTA_UDQ_ACCT work
 
306
                         */
 
307
                                if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
 
308
                                        q_off |= XFS_QUOTA_GDQ_ENFD;
 
309
                                if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
 
310
                                        q_off |= XFS_QUOTA_GDQ_ACCT;
 
311
 
 
312
                                if (q_off !=0) {
 
313
                                        ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
 
314
                                } else {
 
315
                                        ret = 0;
 
316
                                }
 
317
#else
 
318
                                ret = -1;
 
319
#endif
 
320
                        }
 
321
 
 
322
                        break;
 
323
#endif /* HAVE_GROUP_QUOTA */
 
324
                default:
 
325
                        errno = ENOSYS;
 
326
                        return -1;
 
327
        }
 
328
 
 
329
        return ret;
 
330
}
 
331
 
 
332
#else /* HAVE_XFS_QUOTAS */
 
333
 void dummy_sysquotas_xfs(void);
 
334
 
 
335
 void dummy_sysquotas_xfs(void){}
 
336
#endif /* HAVE_XFS_QUOTAS */