]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Jun 2012 17:11:11 +0000 (10:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Jun 2012 17:11:11 +0000 (10:11 -0700)
Pull fuse updates from Miklos Szeredi.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: fix blksize calculation
  fuse: fix stat call on 32 bit platforms
  fuse: optimize fallocate on permanent failure
  fuse: add FALLOCATE operation
  fuse: Convert to kstrtoul_from_user

1  2 
fs/fuse/file.c
fs/fuse/inode.c

diff --combined fs/fuse/file.c
index 9562109d3a879b3dab50ee27d989f3ae89c8b833,bbfd571b37e18233986d44da2a84df9501f6fdd9..b321a688cde79aa0f2923f3440330d03f0e5ee1e
@@@ -962,9 -962,7 +962,9 @@@ static ssize_t fuse_file_aio_write(stru
        if (err)
                goto out;
  
 -      file_update_time(file);
 +      err = file_update_time(file);
 +      if (err)
 +              goto out;
  
        if (file->f_flags & O_DIRECT) {
                written = generic_file_direct_write(iocb, iov, &nr_segs,
@@@ -2173,6 -2171,44 +2173,44 @@@ fuse_direct_IO(int rw, struct kiocb *io
        return ret;
  }
  
+ long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+                           loff_t length)
+ {
+       struct fuse_file *ff = file->private_data;
+       struct fuse_conn *fc = ff->fc;
+       struct fuse_req *req;
+       struct fuse_fallocate_in inarg = {
+               .fh = ff->fh,
+               .offset = offset,
+               .length = length,
+               .mode = mode
+       };
+       int err;
+       if (fc->no_fallocate)
+               return -EOPNOTSUPP;
+       req = fuse_get_req(fc);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+       req->in.h.opcode = FUSE_FALLOCATE;
+       req->in.h.nodeid = ff->nodeid;
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
+       fuse_request_send(fc, req);
+       err = req->out.h.error;
+       if (err == -ENOSYS) {
+               fc->no_fallocate = 1;
+               err = -EOPNOTSUPP;
+       }
+       fuse_put_request(fc, req);
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(fuse_file_fallocate);
  static const struct file_operations fuse_file_operations = {
        .llseek         = fuse_file_llseek,
        .read           = do_sync_read,
        .unlocked_ioctl = fuse_file_ioctl,
        .compat_ioctl   = fuse_file_compat_ioctl,
        .poll           = fuse_file_poll,
+       .fallocate      = fuse_file_fallocate,
  };
  
  static const struct file_operations fuse_direct_io_file_operations = {
        .unlocked_ioctl = fuse_file_ioctl,
        .compat_ioctl   = fuse_file_compat_ioctl,
        .poll           = fuse_file_poll,
+       .fallocate      = fuse_file_fallocate,
        /* no splice_read */
  };
  
diff --combined fs/fuse/inode.c
index 42678a33b7bb6297ced300f7fbb61696d37628c9,a59cf5e673d7406b0cca21eef5549b8d2acb3de9..1cd61652018c7c8547a060344ef998ee6ae96879
@@@ -91,6 -91,7 +91,7 @@@ static struct inode *fuse_alloc_inode(s
        fi->nlookup = 0;
        fi->attr_version = 0;
        fi->writectr = 0;
+       fi->orig_ino = 0;
        INIT_LIST_HEAD(&fi->write_files);
        INIT_LIST_HEAD(&fi->queued_writes);
        INIT_LIST_HEAD(&fi->writepages);
@@@ -122,7 -123,7 +123,7 @@@ static void fuse_destroy_inode(struct i
  static void fuse_evict_inode(struct inode *inode)
  {
        truncate_inode_pages(&inode->i_data, 0);
 -      end_writeback(inode);
 +      clear_inode(inode);
        if (inode->i_sb->s_flags & MS_ACTIVE) {
                struct fuse_conn *fc = get_fuse_conn(inode);
                struct fuse_inode *fi = get_fuse_inode(inode);
@@@ -139,6 -140,18 +140,18 @@@ static int fuse_remount_fs(struct super
        return 0;
  }
  
+ /*
+  * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
+  * so that it will fit.
+  */
+ static ino_t fuse_squash_ino(u64 ino64)
+ {
+       ino_t ino = (ino_t) ino64;
+       if (sizeof(ino_t) < sizeof(u64))
+               ino ^= ino64 >> (sizeof(u64) - sizeof(ino_t)) * 8;
+       return ino;
+ }
  void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
                                   u64 attr_valid)
  {
        fi->attr_version = ++fc->attr_version;
        fi->i_time = attr_valid;
  
-       inode->i_ino     = attr->ino;
+       inode->i_ino     = fuse_squash_ino(attr->ino);
        inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
        set_nlink(inode, attr->nlink);
        inode->i_uid     = attr->uid;
        fi->orig_i_mode = inode->i_mode;
        if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
                inode->i_mode &= ~S_ISVTX;
+       fi->orig_ino = attr->ino;
  }
  
  void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
@@@ -627,10 -642,12 +642,10 @@@ static struct dentry *fuse_get_dentry(s
        return ERR_PTR(err);
  }
  
 -static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
 -                         int connectable)
 +static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len,
 +                         struct inode *parent)
  {
 -      struct inode *inode = dentry->d_inode;
 -      bool encode_parent = connectable && !S_ISDIR(inode->i_mode);
 -      int len = encode_parent ? 6 : 3;
 +      int len = parent ? 6 : 3;
        u64 nodeid;
        u32 generation;
  
        fh[1] = (u32)(nodeid & 0xffffffff);
        fh[2] = generation;
  
 -      if (encode_parent) {
 -              struct inode *parent;
 -
 -              spin_lock(&dentry->d_lock);
 -              parent = dentry->d_parent->d_inode;
 +      if (parent) {
                nodeid = get_fuse_inode(parent)->nodeid;
                generation = parent->i_generation;
 -              spin_unlock(&dentry->d_lock);
  
                fh[3] = (u32)(nodeid >> 32);
                fh[4] = (u32)(nodeid & 0xffffffff);
        }
  
        *max_len = len;
 -      return encode_parent ? 0x82 : 0x81;
 +      return parent ? 0x82 : 0x81;
  }
  
  static struct dentry *fuse_fh_to_dentry(struct super_block *sb,