~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to fs/fuse/dir.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 
11
11
#include <linux/pagemap.h>
12
12
#include <linux/file.h>
13
 
#include <linux/gfp.h>
14
13
#include <linux/sched.h>
15
14
#include <linux/namei.h>
 
15
#include <linux/slab.h>
16
16
 
17
17
#if BITS_PER_LONG >= 64
18
18
static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
156
156
 */
157
157
static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
158
158
{
159
 
        struct inode *inode = entry->d_inode;
160
 
 
 
159
        struct inode *inode;
 
160
 
 
161
        if (nd && nd->flags & LOOKUP_RCU)
 
162
                return -ECHILD;
 
163
 
 
164
        inode = entry->d_inode;
161
165
        if (inode && is_bad_inode(inode))
162
166
                return 0;
163
167
        else if (fuse_dentry_time(entry) < get_jiffies_64()) {
165
169
                struct fuse_entry_out outarg;
166
170
                struct fuse_conn *fc;
167
171
                struct fuse_req *req;
168
 
                struct fuse_req *forget_req;
 
172
                struct fuse_forget_link *forget;
169
173
                struct dentry *parent;
170
174
                u64 attr_version;
171
175
 
178
182
                if (IS_ERR(req))
179
183
                        return 0;
180
184
 
181
 
                forget_req = fuse_get_req(fc);
182
 
                if (IS_ERR(forget_req)) {
 
185
                forget = fuse_alloc_forget();
 
186
                if (!forget) {
183
187
                        fuse_put_request(fc, req);
184
188
                        return 0;
185
189
                }
199
203
                if (!err) {
200
204
                        struct fuse_inode *fi = get_fuse_inode(inode);
201
205
                        if (outarg.nodeid != get_node_id(inode)) {
202
 
                                fuse_send_forget(fc, forget_req,
203
 
                                                 outarg.nodeid, 1);
 
206
                                fuse_queue_forget(fc, forget, outarg.nodeid, 1);
204
207
                                return 0;
205
208
                        }
206
209
                        spin_lock(&fc->lock);
207
210
                        fi->nlookup++;
208
211
                        spin_unlock(&fc->lock);
209
212
                }
210
 
                fuse_put_request(fc, forget_req);
 
213
                kfree(forget);
211
214
                if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
212
215
                        return 0;
213
216
 
259
262
{
260
263
        struct fuse_conn *fc = get_fuse_conn_super(sb);
261
264
        struct fuse_req *req;
262
 
        struct fuse_req *forget_req;
 
265
        struct fuse_forget_link *forget;
263
266
        u64 attr_version;
264
267
        int err;
265
268
 
273
276
        if (IS_ERR(req))
274
277
                goto out;
275
278
 
276
 
        forget_req = fuse_get_req(fc);
277
 
        err = PTR_ERR(forget_req);
278
 
        if (IS_ERR(forget_req)) {
 
279
        forget = fuse_alloc_forget();
 
280
        err = -ENOMEM;
 
281
        if (!forget) {
279
282
                fuse_put_request(fc, req);
280
283
                goto out;
281
284
        }
301
304
                           attr_version);
302
305
        err = -ENOMEM;
303
306
        if (!*inode) {
304
 
                fuse_send_forget(fc, forget_req, outarg->nodeid, 1);
 
307
                fuse_queue_forget(fc, forget, outarg->nodeid, 1);
305
308
                goto out;
306
309
        }
307
310
        err = 0;
308
311
 
309
312
 out_put_forget:
310
 
        fuse_put_request(fc, forget_req);
 
313
        kfree(forget);
311
314
 out:
312
315
        return err;
313
316
}
347
350
        }
348
351
 
349
352
        entry = newent ? newent : entry;
350
 
        entry->d_op = &fuse_dentry_operations;
351
353
        if (outarg_valid)
352
354
                fuse_change_entry_timeout(entry, &outarg);
353
355
        else
374
376
        struct inode *inode;
375
377
        struct fuse_conn *fc = get_fuse_conn(dir);
376
378
        struct fuse_req *req;
377
 
        struct fuse_req *forget_req;
 
379
        struct fuse_forget_link *forget;
378
380
        struct fuse_create_in inarg;
379
381
        struct fuse_open_out outopen;
380
382
        struct fuse_entry_out outentry;
388
390
        if (flags & O_DIRECT)
389
391
                return -EINVAL;
390
392
 
391
 
        forget_req = fuse_get_req(fc);
392
 
        if (IS_ERR(forget_req))
393
 
                return PTR_ERR(forget_req);
 
393
        forget = fuse_alloc_forget();
 
394
        if (!forget)
 
395
                return -ENOMEM;
394
396
 
395
397
        req = fuse_get_req(fc);
396
398
        err = PTR_ERR(req);
448
450
        if (!inode) {
449
451
                flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
450
452
                fuse_sync_release(ff, flags);
451
 
                fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
 
453
                fuse_queue_forget(fc, forget, outentry.nodeid, 1);
452
454
                return -ENOMEM;
453
455
        }
454
 
        fuse_put_request(fc, forget_req);
 
456
        kfree(forget);
455
457
        d_instantiate(entry, inode);
456
458
        fuse_change_entry_timeout(entry, &outentry);
457
459
        fuse_invalidate_attr(dir);
469
471
 out_put_request:
470
472
        fuse_put_request(fc, req);
471
473
 out_put_forget_req:
472
 
        fuse_put_request(fc, forget_req);
 
474
        kfree(forget);
473
475
        return err;
474
476
}
475
477
 
483
485
        struct fuse_entry_out outarg;
484
486
        struct inode *inode;
485
487
        int err;
486
 
        struct fuse_req *forget_req;
 
488
        struct fuse_forget_link *forget;
487
489
 
488
 
        forget_req = fuse_get_req(fc);
489
 
        if (IS_ERR(forget_req)) {
 
490
        forget = fuse_alloc_forget();
 
491
        if (!forget) {
490
492
                fuse_put_request(fc, req);
491
 
                return PTR_ERR(forget_req);
 
493
                return -ENOMEM;
492
494
        }
493
495
 
494
496
        memset(&outarg, 0, sizeof(outarg));
515
517
        inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
516
518
                          &outarg.attr, entry_attr_timeout(&outarg), 0);
517
519
        if (!inode) {
518
 
                fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
 
520
                fuse_queue_forget(fc, forget, outarg.nodeid, 1);
519
521
                return -ENOMEM;
520
522
        }
521
 
        fuse_put_request(fc, forget_req);
 
523
        kfree(forget);
522
524
 
523
525
        if (S_ISDIR(inode->i_mode)) {
524
526
                struct dentry *alias;
541
543
        return 0;
542
544
 
543
545
 out_put_forget_req:
544
 
        fuse_put_request(fc, forget_req);
 
546
        kfree(forget);
545
547
        return err;
546
548
}
547
549
 
981
983
 * access request is sent.  Execute permission is still checked
982
984
 * locally based on file mode.
983
985
 */
984
 
static int fuse_permission(struct inode *inode, int mask)
 
986
static int fuse_permission(struct inode *inode, int mask, unsigned int flags)
985
987
{
986
988
        struct fuse_conn *fc = get_fuse_conn(inode);
987
989
        bool refreshed = false;
988
990
        int err = 0;
989
991
 
 
992
        if (flags & IPERM_FLAG_RCU)
 
993
                return -ECHILD;
 
994
 
990
995
        if (!fuse_allow_task(fc, current))
991
996
                return -EACCES;
992
997
 
1001
1006
        }
1002
1007
 
1003
1008
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
1004
 
                err = generic_permission(inode, mask, NULL);
 
1009
                err = generic_permission(inode, mask, flags, NULL);
1005
1010
 
1006
1011
                /* If permission is denied, try to refresh file
1007
1012
                   attributes.  This is also needed, because the root
1009
1014
                if (err == -EACCES && !refreshed) {
1010
1015
                        err = fuse_do_getattr(inode, NULL, NULL);
1011
1016
                        if (!err)
1012
 
                                err = generic_permission(inode, mask, NULL);
 
1017
                                err = generic_permission(inode, mask,
 
1018
                                                        flags, NULL);
1013
1019
                }
1014
1020
 
1015
1021
                /* Note: the opposite of the above test does not
1016
1022
                   exist.  So if permissions are revoked this won't be
1017
1023
                   noticed immediately, only after the attribute
1018
1024
                   timeout has expired */
1019
 
        } else if (mask & MAY_ACCESS) {
 
1025
        } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
1020
1026
                err = fuse_access(inode, mask);
1021
1027
        } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1022
1028
                if (!(inode->i_mode & S_IXUGO)) {
1156
1162
        return 0;
1157
1163
}
1158
1164
 
1159
 
static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
 
1165
static int fuse_dir_fsync(struct file *file, int datasync)
1160
1166
{
1161
 
        /* nfsd can call this with no file */
1162
 
        return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
 
1167
        return fuse_fsync_common(file, datasync, 1);
1163
1168
}
1164
1169
 
1165
1170
static bool update_mtime(unsigned ivalid)
1271
1276
        if (!fuse_allow_task(fc, current))
1272
1277
                return -EACCES;
1273
1278
 
1274
 
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
1275
 
                err = inode_change_ok(inode, attr);
1276
 
                if (err)
1277
 
                        return err;
 
1279
        if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
 
1280
                attr->ia_valid |= ATTR_FORCE;
 
1281
 
 
1282
        err = inode_change_ok(inode, attr);
 
1283
        if (err)
 
1284
                return err;
 
1285
 
 
1286
        if (attr->ia_valid & ATTR_OPEN) {
 
1287
                if (fc->atomic_o_trunc)
 
1288
                        return 0;
 
1289
                file = NULL;
1278
1290
        }
1279
1291
 
1280
 
        if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
1281
 
                return 0;
1282
 
 
1283
 
        if (attr->ia_valid & ATTR_SIZE) {
1284
 
                err = inode_newsize_ok(inode, attr->ia_size);
1285
 
                if (err)
1286
 
                        return err;
 
1292
        if (attr->ia_valid & ATTR_SIZE)
1287
1293
                is_truncate = true;
1288
 
        }
1289
1294
 
1290
1295
        req = fuse_get_req(fc);
1291
1296
        if (IS_ERR(req))