Back to home page

OSCL-LXR

 
 

    


0001 /*
0002   FUSE: Filesystem in Userspace
0003   Copyright (C) 2001-2018  Miklos Szeredi <miklos@szeredi.hu>
0004 
0005   This program can be distributed under the terms of the GNU GPL.
0006   See the file COPYING.
0007 */
0008 
0009 
0010 #include "fuse_i.h"
0011 #include <linux/iversion.h>
0012 #include <linux/posix_acl.h>
0013 #include <linux/pagemap.h>
0014 #include <linux/highmem.h>
0015 
0016 static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
0017 {
0018     struct fuse_conn *fc = get_fuse_conn(dir);
0019     struct fuse_inode *fi = get_fuse_inode(dir);
0020 
0021     if (!fc->do_readdirplus)
0022         return false;
0023     if (!fc->readdirplus_auto)
0024         return true;
0025     if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
0026         return true;
0027     if (ctx->pos == 0)
0028         return true;
0029     return false;
0030 }
0031 
0032 static void fuse_add_dirent_to_cache(struct file *file,
0033                      struct fuse_dirent *dirent, loff_t pos)
0034 {
0035     struct fuse_inode *fi = get_fuse_inode(file_inode(file));
0036     size_t reclen = FUSE_DIRENT_SIZE(dirent);
0037     pgoff_t index;
0038     struct page *page;
0039     loff_t size;
0040     u64 version;
0041     unsigned int offset;
0042     void *addr;
0043 
0044     spin_lock(&fi->rdc.lock);
0045     /*
0046      * Is cache already completed?  Or this entry does not go at the end of
0047      * cache?
0048      */
0049     if (fi->rdc.cached || pos != fi->rdc.pos) {
0050         spin_unlock(&fi->rdc.lock);
0051         return;
0052     }
0053     version = fi->rdc.version;
0054     size = fi->rdc.size;
0055     offset = size & ~PAGE_MASK;
0056     index = size >> PAGE_SHIFT;
0057     /* Dirent doesn't fit in current page?  Jump to next page. */
0058     if (offset + reclen > PAGE_SIZE) {
0059         index++;
0060         offset = 0;
0061     }
0062     spin_unlock(&fi->rdc.lock);
0063 
0064     if (offset) {
0065         page = find_lock_page(file->f_mapping, index);
0066     } else {
0067         page = find_or_create_page(file->f_mapping, index,
0068                        mapping_gfp_mask(file->f_mapping));
0069     }
0070     if (!page)
0071         return;
0072 
0073     spin_lock(&fi->rdc.lock);
0074     /* Raced with another readdir */
0075     if (fi->rdc.version != version || fi->rdc.size != size ||
0076         WARN_ON(fi->rdc.pos != pos))
0077         goto unlock;
0078 
0079     addr = kmap_local_page(page);
0080     if (!offset)
0081         clear_page(addr);
0082     memcpy(addr + offset, dirent, reclen);
0083     kunmap_local(addr);
0084     fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen;
0085     fi->rdc.pos = dirent->off;
0086 unlock:
0087     spin_unlock(&fi->rdc.lock);
0088     unlock_page(page);
0089     put_page(page);
0090 }
0091 
0092 static void fuse_readdir_cache_end(struct file *file, loff_t pos)
0093 {
0094     struct fuse_inode *fi = get_fuse_inode(file_inode(file));
0095     loff_t end;
0096 
0097     spin_lock(&fi->rdc.lock);
0098     /* does cache end position match current position? */
0099     if (fi->rdc.pos != pos) {
0100         spin_unlock(&fi->rdc.lock);
0101         return;
0102     }
0103 
0104     fi->rdc.cached = true;
0105     end = ALIGN(fi->rdc.size, PAGE_SIZE);
0106     spin_unlock(&fi->rdc.lock);
0107 
0108     /* truncate unused tail of cache */
0109     truncate_inode_pages(file->f_mapping, end);
0110 }
0111 
0112 static bool fuse_emit(struct file *file, struct dir_context *ctx,
0113               struct fuse_dirent *dirent)
0114 {
0115     struct fuse_file *ff = file->private_data;
0116 
0117     if (ff->open_flags & FOPEN_CACHE_DIR)
0118         fuse_add_dirent_to_cache(file, dirent, ctx->pos);
0119 
0120     return dir_emit(ctx, dirent->name, dirent->namelen, dirent->ino,
0121             dirent->type);
0122 }
0123 
0124 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
0125              struct dir_context *ctx)
0126 {
0127     while (nbytes >= FUSE_NAME_OFFSET) {
0128         struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
0129         size_t reclen = FUSE_DIRENT_SIZE(dirent);
0130         if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
0131             return -EIO;
0132         if (reclen > nbytes)
0133             break;
0134         if (memchr(dirent->name, '/', dirent->namelen) != NULL)
0135             return -EIO;
0136 
0137         if (!fuse_emit(file, ctx, dirent))
0138             break;
0139 
0140         buf += reclen;
0141         nbytes -= reclen;
0142         ctx->pos = dirent->off;
0143     }
0144 
0145     return 0;
0146 }
0147 
0148 static int fuse_direntplus_link(struct file *file,
0149                 struct fuse_direntplus *direntplus,
0150                 u64 attr_version)
0151 {
0152     struct fuse_entry_out *o = &direntplus->entry_out;
0153     struct fuse_dirent *dirent = &direntplus->dirent;
0154     struct dentry *parent = file->f_path.dentry;
0155     struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
0156     struct dentry *dentry;
0157     struct dentry *alias;
0158     struct inode *dir = d_inode(parent);
0159     struct fuse_conn *fc;
0160     struct inode *inode;
0161     DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
0162 
0163     if (!o->nodeid) {
0164         /*
0165          * Unlike in the case of fuse_lookup, zero nodeid does not mean
0166          * ENOENT. Instead, it only means the userspace filesystem did
0167          * not want to return attributes/handle for this entry.
0168          *
0169          * So do nothing.
0170          */
0171         return 0;
0172     }
0173 
0174     if (name.name[0] == '.') {
0175         /*
0176          * We could potentially refresh the attributes of the directory
0177          * and its parent?
0178          */
0179         if (name.len == 1)
0180             return 0;
0181         if (name.name[1] == '.' && name.len == 2)
0182             return 0;
0183     }
0184 
0185     if (invalid_nodeid(o->nodeid))
0186         return -EIO;
0187     if (fuse_invalid_attr(&o->attr))
0188         return -EIO;
0189 
0190     fc = get_fuse_conn(dir);
0191 
0192     name.hash = full_name_hash(parent, name.name, name.len);
0193     dentry = d_lookup(parent, &name);
0194     if (!dentry) {
0195 retry:
0196         dentry = d_alloc_parallel(parent, &name, &wq);
0197         if (IS_ERR(dentry))
0198             return PTR_ERR(dentry);
0199     }
0200     if (!d_in_lookup(dentry)) {
0201         struct fuse_inode *fi;
0202         inode = d_inode(dentry);
0203         if (inode && get_node_id(inode) != o->nodeid)
0204             inode = NULL;
0205         if (!inode ||
0206             fuse_stale_inode(inode, o->generation, &o->attr)) {
0207             if (inode)
0208                 fuse_make_bad(inode);
0209             d_invalidate(dentry);
0210             dput(dentry);
0211             goto retry;
0212         }
0213         if (fuse_is_bad(inode)) {
0214             dput(dentry);
0215             return -EIO;
0216         }
0217 
0218         fi = get_fuse_inode(inode);
0219         spin_lock(&fi->lock);
0220         fi->nlookup++;
0221         spin_unlock(&fi->lock);
0222 
0223         forget_all_cached_acls(inode);
0224         fuse_change_attributes(inode, &o->attr,
0225                        entry_attr_timeout(o),
0226                        attr_version);
0227         /*
0228          * The other branch comes via fuse_iget()
0229          * which bumps nlookup inside
0230          */
0231     } else {
0232         inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
0233                   &o->attr, entry_attr_timeout(o),
0234                   attr_version);
0235         if (!inode)
0236             inode = ERR_PTR(-ENOMEM);
0237 
0238         alias = d_splice_alias(inode, dentry);
0239         d_lookup_done(dentry);
0240         if (alias) {
0241             dput(dentry);
0242             dentry = alias;
0243         }
0244         if (IS_ERR(dentry))
0245             return PTR_ERR(dentry);
0246     }
0247     if (fc->readdirplus_auto)
0248         set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
0249     fuse_change_entry_timeout(dentry, o);
0250 
0251     dput(dentry);
0252     return 0;
0253 }
0254 
0255 static void fuse_force_forget(struct file *file, u64 nodeid)
0256 {
0257     struct inode *inode = file_inode(file);
0258     struct fuse_mount *fm = get_fuse_mount(inode);
0259     struct fuse_forget_in inarg;
0260     FUSE_ARGS(args);
0261 
0262     memset(&inarg, 0, sizeof(inarg));
0263     inarg.nlookup = 1;
0264     args.opcode = FUSE_FORGET;
0265     args.nodeid = nodeid;
0266     args.in_numargs = 1;
0267     args.in_args[0].size = sizeof(inarg);
0268     args.in_args[0].value = &inarg;
0269     args.force = true;
0270     args.noreply = true;
0271 
0272     fuse_simple_request(fm, &args);
0273     /* ignore errors */
0274 }
0275 
0276 static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
0277                  struct dir_context *ctx, u64 attr_version)
0278 {
0279     struct fuse_direntplus *direntplus;
0280     struct fuse_dirent *dirent;
0281     size_t reclen;
0282     int over = 0;
0283     int ret;
0284 
0285     while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
0286         direntplus = (struct fuse_direntplus *) buf;
0287         dirent = &direntplus->dirent;
0288         reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
0289 
0290         if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
0291             return -EIO;
0292         if (reclen > nbytes)
0293             break;
0294         if (memchr(dirent->name, '/', dirent->namelen) != NULL)
0295             return -EIO;
0296 
0297         if (!over) {
0298             /* We fill entries into dstbuf only as much as
0299                it can hold. But we still continue iterating
0300                over remaining entries to link them. If not,
0301                we need to send a FORGET for each of those
0302                which we did not link.
0303             */
0304             over = !fuse_emit(file, ctx, dirent);
0305             if (!over)
0306                 ctx->pos = dirent->off;
0307         }
0308 
0309         buf += reclen;
0310         nbytes -= reclen;
0311 
0312         ret = fuse_direntplus_link(file, direntplus, attr_version);
0313         if (ret)
0314             fuse_force_forget(file, direntplus->entry_out.nodeid);
0315     }
0316 
0317     return 0;
0318 }
0319 
0320 static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
0321 {
0322     int plus;
0323     ssize_t res;
0324     struct page *page;
0325     struct inode *inode = file_inode(file);
0326     struct fuse_mount *fm = get_fuse_mount(inode);
0327     struct fuse_io_args ia = {};
0328     struct fuse_args_pages *ap = &ia.ap;
0329     struct fuse_page_desc desc = { .length = PAGE_SIZE };
0330     u64 attr_version = 0;
0331     bool locked;
0332 
0333     page = alloc_page(GFP_KERNEL);
0334     if (!page)
0335         return -ENOMEM;
0336 
0337     plus = fuse_use_readdirplus(inode, ctx);
0338     ap->args.out_pages = true;
0339     ap->num_pages = 1;
0340     ap->pages = &page;
0341     ap->descs = &desc;
0342     if (plus) {
0343         attr_version = fuse_get_attr_version(fm->fc);
0344         fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
0345                     FUSE_READDIRPLUS);
0346     } else {
0347         fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
0348                     FUSE_READDIR);
0349     }
0350     locked = fuse_lock_inode(inode);
0351     res = fuse_simple_request(fm, &ap->args);
0352     fuse_unlock_inode(inode, locked);
0353     if (res >= 0) {
0354         if (!res) {
0355             struct fuse_file *ff = file->private_data;
0356 
0357             if (ff->open_flags & FOPEN_CACHE_DIR)
0358                 fuse_readdir_cache_end(file, ctx->pos);
0359         } else if (plus) {
0360             res = parse_dirplusfile(page_address(page), res,
0361                         file, ctx, attr_version);
0362         } else {
0363             res = parse_dirfile(page_address(page), res, file,
0364                         ctx);
0365         }
0366     }
0367 
0368     __free_page(page);
0369     fuse_invalidate_atime(inode);
0370     return res;
0371 }
0372 
0373 enum fuse_parse_result {
0374     FOUND_ERR = -1,
0375     FOUND_NONE = 0,
0376     FOUND_SOME,
0377     FOUND_ALL,
0378 };
0379 
0380 static enum fuse_parse_result fuse_parse_cache(struct fuse_file *ff,
0381                            void *addr, unsigned int size,
0382                            struct dir_context *ctx)
0383 {
0384     unsigned int offset = ff->readdir.cache_off & ~PAGE_MASK;
0385     enum fuse_parse_result res = FOUND_NONE;
0386 
0387     WARN_ON(offset >= size);
0388 
0389     for (;;) {
0390         struct fuse_dirent *dirent = addr + offset;
0391         unsigned int nbytes = size - offset;
0392         size_t reclen;
0393 
0394         if (nbytes < FUSE_NAME_OFFSET || !dirent->namelen)
0395             break;
0396 
0397         reclen = FUSE_DIRENT_SIZE(dirent); /* derefs ->namelen */
0398 
0399         if (WARN_ON(dirent->namelen > FUSE_NAME_MAX))
0400             return FOUND_ERR;
0401         if (WARN_ON(reclen > nbytes))
0402             return FOUND_ERR;
0403         if (WARN_ON(memchr(dirent->name, '/', dirent->namelen) != NULL))
0404             return FOUND_ERR;
0405 
0406         if (ff->readdir.pos == ctx->pos) {
0407             res = FOUND_SOME;
0408             if (!dir_emit(ctx, dirent->name, dirent->namelen,
0409                       dirent->ino, dirent->type))
0410                 return FOUND_ALL;
0411             ctx->pos = dirent->off;
0412         }
0413         ff->readdir.pos = dirent->off;
0414         ff->readdir.cache_off += reclen;
0415 
0416         offset += reclen;
0417     }
0418 
0419     return res;
0420 }
0421 
0422 static void fuse_rdc_reset(struct inode *inode)
0423 {
0424     struct fuse_inode *fi = get_fuse_inode(inode);
0425 
0426     fi->rdc.cached = false;
0427     fi->rdc.version++;
0428     fi->rdc.size = 0;
0429     fi->rdc.pos = 0;
0430 }
0431 
0432 #define UNCACHED 1
0433 
0434 static int fuse_readdir_cached(struct file *file, struct dir_context *ctx)
0435 {
0436     struct fuse_file *ff = file->private_data;
0437     struct inode *inode = file_inode(file);
0438     struct fuse_conn *fc = get_fuse_conn(inode);
0439     struct fuse_inode *fi = get_fuse_inode(inode);
0440     enum fuse_parse_result res;
0441     pgoff_t index;
0442     unsigned int size;
0443     struct page *page;
0444     void *addr;
0445 
0446     /* Seeked?  If so, reset the cache stream */
0447     if (ff->readdir.pos != ctx->pos) {
0448         ff->readdir.pos = 0;
0449         ff->readdir.cache_off = 0;
0450     }
0451 
0452     /*
0453      * We're just about to start reading into the cache or reading the
0454      * cache; both cases require an up-to-date mtime value.
0455      */
0456     if (!ctx->pos && fc->auto_inval_data) {
0457         int err = fuse_update_attributes(inode, file, STATX_MTIME);
0458 
0459         if (err)
0460             return err;
0461     }
0462 
0463 retry:
0464     spin_lock(&fi->rdc.lock);
0465 retry_locked:
0466     if (!fi->rdc.cached) {
0467         /* Starting cache? Set cache mtime. */
0468         if (!ctx->pos && !fi->rdc.size) {
0469             fi->rdc.mtime = inode->i_mtime;
0470             fi->rdc.iversion = inode_query_iversion(inode);
0471         }
0472         spin_unlock(&fi->rdc.lock);
0473         return UNCACHED;
0474     }
0475     /*
0476      * When at the beginning of the directory (i.e. just after opendir(3) or
0477      * rewinddir(3)), then need to check whether directory contents have
0478      * changed, and reset the cache if so.
0479      */
0480     if (!ctx->pos) {
0481         if (inode_peek_iversion(inode) != fi->rdc.iversion ||
0482             !timespec64_equal(&fi->rdc.mtime, &inode->i_mtime)) {
0483             fuse_rdc_reset(inode);
0484             goto retry_locked;
0485         }
0486     }
0487 
0488     /*
0489      * If cache version changed since the last getdents() call, then reset
0490      * the cache stream.
0491      */
0492     if (ff->readdir.version != fi->rdc.version) {
0493         ff->readdir.pos = 0;
0494         ff->readdir.cache_off = 0;
0495     }
0496     /*
0497      * If at the beginning of the cache, than reset version to
0498      * current.
0499      */
0500     if (ff->readdir.pos == 0)
0501         ff->readdir.version = fi->rdc.version;
0502 
0503     WARN_ON(fi->rdc.size < ff->readdir.cache_off);
0504 
0505     index = ff->readdir.cache_off >> PAGE_SHIFT;
0506 
0507     if (index == (fi->rdc.size >> PAGE_SHIFT))
0508         size = fi->rdc.size & ~PAGE_MASK;
0509     else
0510         size = PAGE_SIZE;
0511     spin_unlock(&fi->rdc.lock);
0512 
0513     /* EOF? */
0514     if ((ff->readdir.cache_off & ~PAGE_MASK) == size)
0515         return 0;
0516 
0517     page = find_get_page_flags(file->f_mapping, index,
0518                    FGP_ACCESSED | FGP_LOCK);
0519     spin_lock(&fi->rdc.lock);
0520     if (!page) {
0521         /*
0522          * Uh-oh: page gone missing, cache is useless
0523          */
0524         if (fi->rdc.version == ff->readdir.version)
0525             fuse_rdc_reset(inode);
0526         goto retry_locked;
0527     }
0528 
0529     /* Make sure it's still the same version after getting the page. */
0530     if (ff->readdir.version != fi->rdc.version) {
0531         spin_unlock(&fi->rdc.lock);
0532         unlock_page(page);
0533         put_page(page);
0534         goto retry;
0535     }
0536     spin_unlock(&fi->rdc.lock);
0537 
0538     /*
0539      * Contents of the page are now protected against changing by holding
0540      * the page lock.
0541      */
0542     addr = kmap(page);
0543     res = fuse_parse_cache(ff, addr, size, ctx);
0544     kunmap(page);
0545     unlock_page(page);
0546     put_page(page);
0547 
0548     if (res == FOUND_ERR)
0549         return -EIO;
0550 
0551     if (res == FOUND_ALL)
0552         return 0;
0553 
0554     if (size == PAGE_SIZE) {
0555         /* We hit end of page: skip to next page. */
0556         ff->readdir.cache_off = ALIGN(ff->readdir.cache_off, PAGE_SIZE);
0557         goto retry;
0558     }
0559 
0560     /*
0561      * End of cache reached.  If found position, then we are done, otherwise
0562      * need to fall back to uncached, since the position we were looking for
0563      * wasn't in the cache.
0564      */
0565     return res == FOUND_SOME ? 0 : UNCACHED;
0566 }
0567 
0568 int fuse_readdir(struct file *file, struct dir_context *ctx)
0569 {
0570     struct fuse_file *ff = file->private_data;
0571     struct inode *inode = file_inode(file);
0572     int err;
0573 
0574     if (fuse_is_bad(inode))
0575         return -EIO;
0576 
0577     mutex_lock(&ff->readdir.lock);
0578 
0579     err = UNCACHED;
0580     if (ff->open_flags & FOPEN_CACHE_DIR)
0581         err = fuse_readdir_cached(file, ctx);
0582     if (err == UNCACHED)
0583         err = fuse_readdir_uncached(file, ctx);
0584 
0585     mutex_unlock(&ff->readdir.lock);
0586 
0587     return err;
0588 }