You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge from Linus' tree
This commit is contained in:
+66
-114
@@ -175,16 +175,16 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_read - read from a file (internal)
|
||||
* v9fs_file_read - read from a file
|
||||
* @filep: file pointer to read
|
||||
* @data: data buffer to read data into
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to read data
|
||||
*
|
||||
*/
|
||||
|
||||
static ssize_t
|
||||
v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
|
||||
v9fs_file_read(struct file *filp, char __user * data, size_t count,
|
||||
loff_t * offset)
|
||||
{
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
||||
@@ -194,6 +194,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
|
||||
int rsize = 0;
|
||||
int result = 0;
|
||||
int total = 0;
|
||||
int n;
|
||||
|
||||
dprintk(DEBUG_VFS, "\n");
|
||||
|
||||
@@ -216,10 +217,15 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
|
||||
} else
|
||||
*offset += result;
|
||||
|
||||
/* XXX - extra copy */
|
||||
memcpy(buffer, fcall->params.rread.data, result);
|
||||
n = copy_to_user(data, fcall->params.rread.data, result);
|
||||
if (n) {
|
||||
dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n);
|
||||
kfree(fcall);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
count -= result;
|
||||
buffer += result;
|
||||
data += result;
|
||||
total += result;
|
||||
|
||||
kfree(fcall);
|
||||
@@ -231,101 +237,6 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_file_read - read from a file
|
||||
* @filep: file pointer to read
|
||||
* @data: data buffer to read data into
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to read data
|
||||
*
|
||||
*/
|
||||
|
||||
static ssize_t
|
||||
v9fs_file_read(struct file *filp, char __user * data, size_t count,
|
||||
loff_t * offset)
|
||||
{
|
||||
int retval = -1;
|
||||
int ret = 0;
|
||||
char *buffer;
|
||||
|
||||
buffer = kmalloc(count, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
retval = v9fs_read(filp, buffer, count, offset);
|
||||
if (retval > 0) {
|
||||
if ((ret = copy_to_user(data, buffer, retval)) != 0) {
|
||||
dprintk(DEBUG_ERROR, "Problem copying to user %d\n",
|
||||
ret);
|
||||
retval = ret;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(buffer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_write - write to a file
|
||||
* @filep: file pointer to write
|
||||
* @data: data buffer to write data from
|
||||
* @count: size of buffer
|
||||
* @offset: offset at which to write data
|
||||
*
|
||||
*/
|
||||
|
||||
static ssize_t
|
||||
v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
|
||||
{
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
||||
struct v9fs_fid *v9fid = filp->private_data;
|
||||
struct v9fs_fcall *fcall;
|
||||
int fid = v9fid->fid;
|
||||
int result = -EIO;
|
||||
int rsize = 0;
|
||||
int total = 0;
|
||||
|
||||
dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count,
|
||||
(int)*offset);
|
||||
rsize = v9ses->maxdata - V9FS_IOHDRSZ;
|
||||
if (v9fid->iounit != 0 && rsize > v9fid->iounit)
|
||||
rsize = v9fid->iounit;
|
||||
|
||||
dump_data(buffer, count);
|
||||
|
||||
do {
|
||||
if (count < rsize)
|
||||
rsize = count;
|
||||
|
||||
result =
|
||||
v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall);
|
||||
if (result < 0) {
|
||||
eprintk(KERN_ERR, "error while writing: %s(%d)\n",
|
||||
FCALL_ERROR(fcall), result);
|
||||
kfree(fcall);
|
||||
return result;
|
||||
} else
|
||||
*offset += result;
|
||||
|
||||
kfree(fcall);
|
||||
|
||||
if (result != rsize) {
|
||||
eprintk(KERN_ERR,
|
||||
"short write: v9fs_t_write returned %d\n",
|
||||
result);
|
||||
break;
|
||||
}
|
||||
|
||||
count -= result;
|
||||
buffer += result;
|
||||
total += result;
|
||||
} while (count);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_file_write - write to a file
|
||||
* @filep: file pointer to write
|
||||
@@ -339,24 +250,65 @@ static ssize_t
|
||||
v9fs_file_write(struct file *filp, const char __user * data,
|
||||
size_t count, loff_t * offset)
|
||||
{
|
||||
int ret = -1;
|
||||
char *buffer;
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
||||
struct v9fs_fid *v9fid = filp->private_data;
|
||||
struct v9fs_fcall *fcall;
|
||||
int fid = v9fid->fid;
|
||||
int result = -EIO;
|
||||
int rsize = 0;
|
||||
int total = 0;
|
||||
char *buf;
|
||||
|
||||
buffer = kmalloc(count, GFP_KERNEL);
|
||||
if (buffer == NULL)
|
||||
dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
|
||||
(int)*offset);
|
||||
rsize = v9ses->maxdata - V9FS_IOHDRSZ;
|
||||
if (v9fid->iounit != 0 && rsize > v9fid->iounit)
|
||||
rsize = v9fid->iounit;
|
||||
|
||||
buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = copy_from_user(buffer, data, count);
|
||||
if (ret) {
|
||||
dprintk(DEBUG_ERROR, "Problem copying from user\n");
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ret = v9fs_write(filp, buffer, count, offset);
|
||||
}
|
||||
do {
|
||||
if (count < rsize)
|
||||
rsize = count;
|
||||
|
||||
kfree(buffer);
|
||||
result = copy_from_user(buf, data, rsize);
|
||||
if (result) {
|
||||
dprintk(DEBUG_ERROR, "Problem copying from user\n");
|
||||
kfree(buf);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
dump_data(buf, rsize);
|
||||
result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
|
||||
if (result < 0) {
|
||||
eprintk(KERN_ERR, "error while writing: %s(%d)\n",
|
||||
FCALL_ERROR(fcall), result);
|
||||
kfree(fcall);
|
||||
kfree(buf);
|
||||
return result;
|
||||
} else
|
||||
*offset += result;
|
||||
|
||||
kfree(fcall);
|
||||
fcall = NULL;
|
||||
|
||||
if (result != rsize) {
|
||||
eprintk(KERN_ERR,
|
||||
"short write: v9fs_t_write returned %d\n",
|
||||
result);
|
||||
break;
|
||||
}
|
||||
|
||||
count -= result;
|
||||
data += result;
|
||||
total += result;
|
||||
} while (count);
|
||||
|
||||
kfree(buf);
|
||||
return total;
|
||||
}
|
||||
|
||||
struct file_operations v9fs_file_operations = {
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type
|
||||
|
||||
if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
|
||||
dprintk(DEBUG_ERROR, "problem initiating session\n");
|
||||
return newfid;
|
||||
return ERR_PTR(newfid);
|
||||
}
|
||||
|
||||
sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
|
||||
|
||||
@@ -741,19 +741,9 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
|
||||
ret = retry(iocb);
|
||||
current->io_wait = NULL;
|
||||
|
||||
if (-EIOCBRETRY != ret) {
|
||||
if (-EIOCBQUEUED != ret) {
|
||||
BUG_ON(!list_empty(&iocb->ki_wait.task_list));
|
||||
aio_complete(iocb, ret, 0);
|
||||
/* must not access the iocb after this */
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Issue an additional retry to avoid waiting forever if
|
||||
* no waits were queued (e.g. in case of a short read).
|
||||
*/
|
||||
if (list_empty(&iocb->ki_wait.task_list))
|
||||
kiocbSetKicked(iocb);
|
||||
if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
|
||||
BUG_ON(!list_empty(&iocb->ki_wait.task_list));
|
||||
aio_complete(iocb, ret, 0);
|
||||
}
|
||||
out:
|
||||
spin_lock_irq(&ctx->ctx_lock);
|
||||
@@ -899,16 +889,24 @@ static void aio_kick_handler(void *data)
|
||||
* and if required activate the aio work queue to process
|
||||
* it
|
||||
*/
|
||||
static void queue_kicked_iocb(struct kiocb *iocb)
|
||||
static void try_queue_kicked_iocb(struct kiocb *iocb)
|
||||
{
|
||||
struct kioctx *ctx = iocb->ki_ctx;
|
||||
unsigned long flags;
|
||||
int run = 0;
|
||||
|
||||
WARN_ON((!list_empty(&iocb->ki_wait.task_list)));
|
||||
/* We're supposed to be the only path putting the iocb back on the run
|
||||
* list. If we find that the iocb is *back* on a wait queue already
|
||||
* than retry has happened before we could queue the iocb. This also
|
||||
* means that the retry could have completed and freed our iocb, no
|
||||
* good. */
|
||||
BUG_ON((!list_empty(&iocb->ki_wait.task_list)));
|
||||
|
||||
spin_lock_irqsave(&ctx->ctx_lock, flags);
|
||||
run = __queue_kicked_iocb(iocb);
|
||||
/* set this inside the lock so that we can't race with aio_run_iocb()
|
||||
* testing it and putting the iocb on the run list under the lock */
|
||||
if (!kiocbTryKick(iocb))
|
||||
run = __queue_kicked_iocb(iocb);
|
||||
spin_unlock_irqrestore(&ctx->ctx_lock, flags);
|
||||
if (run)
|
||||
aio_queue_work(ctx);
|
||||
@@ -931,10 +929,7 @@ void fastcall kick_iocb(struct kiocb *iocb)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If its already kicked we shouldn't queue it again */
|
||||
if (!kiocbTryKick(iocb)) {
|
||||
queue_kicked_iocb(iocb);
|
||||
}
|
||||
try_queue_kicked_iocb(iocb);
|
||||
}
|
||||
EXPORT_SYMBOL(kick_iocb);
|
||||
|
||||
@@ -1322,8 +1317,11 @@ asmlinkage long sys_io_destroy(aio_context_t ctx)
|
||||
}
|
||||
|
||||
/*
|
||||
* Default retry method for aio_read (also used for first time submit)
|
||||
* Responsible for updating iocb state as retries progress
|
||||
* aio_p{read,write} are the default ki_retry methods for
|
||||
* IO_CMD_P{READ,WRITE}. They maintains kiocb retry state around potentially
|
||||
* multiple calls to f_op->aio_read(). They loop around partial progress
|
||||
* instead of returning -EIOCBRETRY because they don't have the means to call
|
||||
* kick_iocb().
|
||||
*/
|
||||
static ssize_t aio_pread(struct kiocb *iocb)
|
||||
{
|
||||
@@ -1332,25 +1330,25 @@ static ssize_t aio_pread(struct kiocb *iocb)
|
||||
struct inode *inode = mapping->host;
|
||||
ssize_t ret = 0;
|
||||
|
||||
ret = file->f_op->aio_read(iocb, iocb->ki_buf,
|
||||
iocb->ki_left, iocb->ki_pos);
|
||||
|
||||
/*
|
||||
* Can't just depend on iocb->ki_left to determine
|
||||
* whether we are done. This may have been a short read.
|
||||
*/
|
||||
if (ret > 0) {
|
||||
iocb->ki_buf += ret;
|
||||
iocb->ki_left -= ret;
|
||||
do {
|
||||
ret = file->f_op->aio_read(iocb, iocb->ki_buf,
|
||||
iocb->ki_left, iocb->ki_pos);
|
||||
/*
|
||||
* For pipes and sockets we return once we have
|
||||
* some data; for regular files we retry till we
|
||||
* complete the entire read or find that we can't
|
||||
* read any more data (e.g short reads).
|
||||
* Can't just depend on iocb->ki_left to determine
|
||||
* whether we are done. This may have been a short read.
|
||||
*/
|
||||
if (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))
|
||||
ret = -EIOCBRETRY;
|
||||
}
|
||||
if (ret > 0) {
|
||||
iocb->ki_buf += ret;
|
||||
iocb->ki_left -= ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* For pipes and sockets we return once we have some data; for
|
||||
* regular files we retry till we complete the entire read or
|
||||
* find that we can't read any more data (e.g short reads).
|
||||
*/
|
||||
} while (ret > 0 && iocb->ki_left > 0 &&
|
||||
!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode));
|
||||
|
||||
/* This means we must have transferred all that we could */
|
||||
/* No need to retry anymore */
|
||||
@@ -1360,27 +1358,21 @@ static ssize_t aio_pread(struct kiocb *iocb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Default retry method for aio_write (also used for first time submit)
|
||||
* Responsible for updating iocb state as retries progress
|
||||
*/
|
||||
/* see aio_pread() */
|
||||
static ssize_t aio_pwrite(struct kiocb *iocb)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
ssize_t ret = 0;
|
||||
|
||||
ret = file->f_op->aio_write(iocb, iocb->ki_buf,
|
||||
iocb->ki_left, iocb->ki_pos);
|
||||
do {
|
||||
ret = file->f_op->aio_write(iocb, iocb->ki_buf,
|
||||
iocb->ki_left, iocb->ki_pos);
|
||||
if (ret > 0) {
|
||||
iocb->ki_buf += ret;
|
||||
iocb->ki_left -= ret;
|
||||
}
|
||||
} while (ret > 0 && iocb->ki_left > 0);
|
||||
|
||||
if (ret > 0) {
|
||||
iocb->ki_buf += ret;
|
||||
iocb->ki_left -= ret;
|
||||
|
||||
ret = -EIOCBRETRY;
|
||||
}
|
||||
|
||||
/* This means we must have transferred all that we could */
|
||||
/* No need to retry anymore */
|
||||
if ((ret == 0) || (iocb->ki_left == 0))
|
||||
ret = iocb->ki_nbytes - iocb->ki_left;
|
||||
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
|
||||
inode->i_mapping->a_ops = &bfs_aops;
|
||||
inode->i_mode = mode;
|
||||
inode->i_ino = ino;
|
||||
BFS_I(inode)->i_dsk_ino = cpu_to_le16(ino);
|
||||
BFS_I(inode)->i_dsk_ino = ino;
|
||||
BFS_I(inode)->i_sblock = 0;
|
||||
BFS_I(inode)->i_eblock = 0;
|
||||
insert_inode_hash(inode);
|
||||
|
||||
+31
-13
@@ -357,28 +357,46 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
|
||||
}
|
||||
|
||||
info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
|
||||
info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - cpu_to_le32(bfs_sb->s_start))>>BFS_BSIZE_BITS;
|
||||
info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - le32_to_cpu(bfs_sb->s_start))>>BFS_BSIZE_BITS;
|
||||
info->si_freei = 0;
|
||||
info->si_lf_eblk = 0;
|
||||
info->si_lf_sblk = 0;
|
||||
info->si_lf_ioff = 0;
|
||||
bh = NULL;
|
||||
for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
|
||||
inode = iget(s,i);
|
||||
if (BFS_I(inode)->i_dsk_ino == 0)
|
||||
struct bfs_inode *di;
|
||||
int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
|
||||
int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
|
||||
unsigned long sblock, eblock;
|
||||
|
||||
if (!off) {
|
||||
brelse(bh);
|
||||
bh = sb_bread(s, block);
|
||||
}
|
||||
|
||||
if (!bh)
|
||||
continue;
|
||||
|
||||
di = (struct bfs_inode *)bh->b_data + off;
|
||||
|
||||
if (!di->i_ino) {
|
||||
info->si_freei++;
|
||||
else {
|
||||
set_bit(i, info->si_imap);
|
||||
info->si_freeb -= inode->i_blocks;
|
||||
if (BFS_I(inode)->i_eblock > info->si_lf_eblk) {
|
||||
info->si_lf_eblk = BFS_I(inode)->i_eblock;
|
||||
info->si_lf_sblk = BFS_I(inode)->i_sblock;
|
||||
info->si_lf_ioff = BFS_INO2OFF(i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
set_bit(i, info->si_imap);
|
||||
info->si_freeb -= BFS_FILEBLOCKS(di);
|
||||
|
||||
sblock = le32_to_cpu(di->i_sblock);
|
||||
eblock = le32_to_cpu(di->i_eblock);
|
||||
if (eblock > info->si_lf_eblk) {
|
||||
info->si_lf_eblk = eblock;
|
||||
info->si_lf_sblk = sblock;
|
||||
info->si_lf_ioff = BFS_INO2OFF(i);
|
||||
}
|
||||
iput(inode);
|
||||
}
|
||||
brelse(bh);
|
||||
if (!(s->s_flags & MS_RDONLY)) {
|
||||
mark_buffer_dirty(bh);
|
||||
mark_buffer_dirty(info->si_sbh);
|
||||
s->s_dirt = 1;
|
||||
}
|
||||
dump_imap("read_super", s);
|
||||
|
||||
+1
-1
@@ -905,7 +905,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
||||
send_sig(SIGKILL, current, 0);
|
||||
goto out_free_dentry;
|
||||
}
|
||||
if (padzero(elf_bss)) {
|
||||
if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
|
||||
send_sig(SIGSEGV, current, 0);
|
||||
retval = -EFAULT; /* Nobody gets to see this, but.. */
|
||||
goto out_free_dentry;
|
||||
|
||||
@@ -75,7 +75,7 @@ struct bio_set {
|
||||
*/
|
||||
static struct bio_set *fs_bio_set;
|
||||
|
||||
static inline struct bio_vec *bvec_alloc_bs(unsigned int __nocast gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
|
||||
static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
|
||||
{
|
||||
struct bio_vec *bvl;
|
||||
struct biovec_slab *bp;
|
||||
@@ -155,7 +155,7 @@ inline void bio_init(struct bio *bio)
|
||||
* allocate bio and iovecs from the memory pools specified by the
|
||||
* bio_set structure.
|
||||
**/
|
||||
struct bio *bio_alloc_bioset(unsigned int __nocast gfp_mask, int nr_iovecs, struct bio_set *bs)
|
||||
struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
|
||||
{
|
||||
struct bio *bio = mempool_alloc(bs->bio_pool, gfp_mask);
|
||||
|
||||
@@ -181,7 +181,7 @@ out:
|
||||
return bio;
|
||||
}
|
||||
|
||||
struct bio *bio_alloc(unsigned int __nocast gfp_mask, int nr_iovecs)
|
||||
struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
|
||||
{
|
||||
struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
|
||||
|
||||
@@ -277,7 +277,7 @@ inline void __bio_clone(struct bio *bio, struct bio *bio_src)
|
||||
*
|
||||
* Like __bio_clone, only also allocates the returned bio
|
||||
*/
|
||||
struct bio *bio_clone(struct bio *bio, unsigned int __nocast gfp_mask)
|
||||
struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
|
||||
{
|
||||
struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set);
|
||||
|
||||
@@ -1078,7 +1078,7 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
|
||||
return bp;
|
||||
}
|
||||
|
||||
static void *bio_pair_alloc(unsigned int __nocast gfp_flags, void *data)
|
||||
static void *bio_pair_alloc(gfp_t gfp_flags, void *data)
|
||||
{
|
||||
return kmalloc(sizeof(struct bio_pair), gfp_flags);
|
||||
}
|
||||
|
||||
+1
-1
@@ -3045,7 +3045,7 @@ static void recalc_bh_state(void)
|
||||
buffer_heads_over_limit = (tot > max_buffer_heads);
|
||||
}
|
||||
|
||||
struct buffer_head *alloc_buffer_head(unsigned int __nocast gfp_flags)
|
||||
struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
|
||||
{
|
||||
struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags);
|
||||
if (ret) {
|
||||
|
||||
@@ -23,6 +23,10 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
|
||||
struct fuse_file *ff;
|
||||
int err;
|
||||
|
||||
/* VFS checks this, but only _after_ ->open() */
|
||||
if (file->f_flags & O_DIRECT)
|
||||
return -EINVAL;
|
||||
|
||||
err = generic_file_open(inode, file);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -793,11 +793,6 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
|
||||
return(err);
|
||||
}
|
||||
|
||||
void hostfs_truncate(struct inode *ino)
|
||||
{
|
||||
not_implemented();
|
||||
}
|
||||
|
||||
int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
|
||||
{
|
||||
char *name;
|
||||
@@ -894,7 +889,6 @@ static struct inode_operations hostfs_iops = {
|
||||
.rmdir = hostfs_rmdir,
|
||||
.mknod = hostfs_mknod,
|
||||
.rename = hostfs_rename,
|
||||
.truncate = hostfs_truncate,
|
||||
.permission = hostfs_permission,
|
||||
.setattr = hostfs_setattr,
|
||||
.getattr = hostfs_getattr,
|
||||
@@ -910,7 +904,6 @@ static struct inode_operations hostfs_dir_iops = {
|
||||
.rmdir = hostfs_rmdir,
|
||||
.mknod = hostfs_mknod,
|
||||
.rename = hostfs_rename,
|
||||
.truncate = hostfs_truncate,
|
||||
.permission = hostfs_permission,
|
||||
.setattr = hostfs_setattr,
|
||||
.getattr = hostfs_getattr,
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ static struct bio *mpage_bio_submit(int rw, struct bio *bio)
|
||||
static struct bio *
|
||||
mpage_alloc(struct block_device *bdev,
|
||||
sector_t first_sector, int nr_vecs,
|
||||
unsigned int __nocast gfp_flags)
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct bio *bio;
|
||||
|
||||
|
||||
+3
-3
@@ -1551,19 +1551,19 @@ do_link:
|
||||
if (nd->last_type != LAST_NORM)
|
||||
goto exit;
|
||||
if (nd->last.name[nd->last.len]) {
|
||||
putname(nd->last.name);
|
||||
__putname(nd->last.name);
|
||||
goto exit;
|
||||
}
|
||||
error = -ELOOP;
|
||||
if (count++==32) {
|
||||
putname(nd->last.name);
|
||||
__putname(nd->last.name);
|
||||
goto exit;
|
||||
}
|
||||
dir = nd->dentry;
|
||||
down(&dir->d_inode->i_sem);
|
||||
path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
|
||||
path.mnt = nd->mnt;
|
||||
putname(nd->last.name);
|
||||
__putname(nd->last.name);
|
||||
goto do_last;
|
||||
}
|
||||
|
||||
|
||||
+35
-35
@@ -48,43 +48,26 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
|
||||
(struct nfsacl_encode_desc *) desc;
|
||||
u32 *p = (u32 *) elem;
|
||||
|
||||
if (nfsacl_desc->count < nfsacl_desc->acl->a_count) {
|
||||
struct posix_acl_entry *entry =
|
||||
&nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
|
||||
struct posix_acl_entry *entry =
|
||||
&nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
|
||||
|
||||
*p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
|
||||
switch(entry->e_tag) {
|
||||
case ACL_USER_OBJ:
|
||||
*p++ = htonl(nfsacl_desc->uid);
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
*p++ = htonl(nfsacl_desc->gid);
|
||||
break;
|
||||
case ACL_USER:
|
||||
case ACL_GROUP:
|
||||
*p++ = htonl(entry->e_id);
|
||||
break;
|
||||
default: /* Solaris depends on that! */
|
||||
*p++ = 0;
|
||||
break;
|
||||
}
|
||||
*p++ = htonl(entry->e_perm & S_IRWXO);
|
||||
} else {
|
||||
const struct posix_acl_entry *pa, *pe;
|
||||
int group_obj_perm = ACL_READ|ACL_WRITE|ACL_EXECUTE;
|
||||
|
||||
FOREACH_ACL_ENTRY(pa, nfsacl_desc->acl, pe) {
|
||||
if (pa->e_tag == ACL_GROUP_OBJ) {
|
||||
group_obj_perm = pa->e_perm & S_IRWXO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* fake up ACL_MASK entry */
|
||||
*p++ = htonl(ACL_MASK | nfsacl_desc->typeflag);
|
||||
*p++ = htonl(0);
|
||||
*p++ = htonl(group_obj_perm);
|
||||
*p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
|
||||
switch(entry->e_tag) {
|
||||
case ACL_USER_OBJ:
|
||||
*p++ = htonl(nfsacl_desc->uid);
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
*p++ = htonl(nfsacl_desc->gid);
|
||||
break;
|
||||
case ACL_USER:
|
||||
case ACL_GROUP:
|
||||
*p++ = htonl(entry->e_id);
|
||||
break;
|
||||
default: /* Solaris depends on that! */
|
||||
*p++ = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = htonl(entry->e_perm & S_IRWXO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -105,11 +88,28 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
|
||||
.gid = inode->i_gid,
|
||||
};
|
||||
int err;
|
||||
struct posix_acl *acl2 = NULL;
|
||||
|
||||
if (entries > NFS_ACL_MAX_ENTRIES ||
|
||||
xdr_encode_word(buf, base, entries))
|
||||
return -EINVAL;
|
||||
if (encode_entries && acl && acl->a_count == 3) {
|
||||
/* Fake up an ACL_MASK entry. */
|
||||
acl2 = posix_acl_alloc(4, GFP_KERNEL);
|
||||
if (!acl2)
|
||||
return -ENOMEM;
|
||||
/* Insert entries in canonical order: other orders seem
|
||||
to confuse Solaris VxFS. */
|
||||
acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */
|
||||
acl2->a_entries[1] = acl->a_entries[1]; /* ACL_GROUP_OBJ */
|
||||
acl2->a_entries[2] = acl->a_entries[1]; /* ACL_MASK */
|
||||
acl2->a_entries[2].e_tag = ACL_MASK;
|
||||
acl2->a_entries[3] = acl->a_entries[2]; /* ACL_OTHER */
|
||||
nfsacl_desc.acl = acl2;
|
||||
}
|
||||
err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
|
||||
if (acl2)
|
||||
posix_acl_release(acl2);
|
||||
if (!err)
|
||||
err = 8 + nfsacl_desc.desc.elem_size *
|
||||
nfsacl_desc.desc.array_len;
|
||||
|
||||
@@ -102,6 +102,9 @@ ToDo/Notes:
|
||||
inode instead of a vfs inode as parameter.
|
||||
- Fix the definition of the CHKD ntfs record magic. It had an off by
|
||||
two error causing it to be CHKB instead of CHKD.
|
||||
- Fix a stupid bug in __ntfs_bitmap_set_bits_in_run() which caused the
|
||||
count to become negative and hence we had a wild memset() scribbling
|
||||
all over the system's ram.
|
||||
|
||||
2.1.23 - Implement extension of resident files and make writing safe as well as
|
||||
many bug fixes, cleanups, and enhancements...
|
||||
|
||||
+3
-2
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* bitmap.c - NTFS kernel bitmap handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004 Anton Altaparmakov
|
||||
* Copyright (c) 2004-2005 Anton Altaparmakov
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
@@ -90,7 +90,8 @@ int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
|
||||
/* If the first byte is partial, modify the appropriate bits in it. */
|
||||
if (bit) {
|
||||
u8 *byte = kaddr + pos;
|
||||
while ((bit & 7) && cnt--) {
|
||||
while ((bit & 7) && cnt) {
|
||||
cnt--;
|
||||
if (value)
|
||||
*byte |= 1 << bit++;
|
||||
else
|
||||
|
||||
+1
-1
@@ -309,7 +309,7 @@ typedef le16 MFT_RECORD_FLAGS;
|
||||
* Note: The _LE versions will return a CPU endian formatted value!
|
||||
*/
|
||||
#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
|
||||
#define MFT_REF_MASK_LE const_cpu_to_le64(0x0000ffffffffffffULL)
|
||||
#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
|
||||
|
||||
typedef u64 MFT_REF;
|
||||
typedef le64 leMFT_REF;
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
* Depending on @gfp_mask the allocation may be guaranteed to succeed.
|
||||
*/
|
||||
static inline void *__ntfs_malloc(unsigned long size,
|
||||
unsigned int __nocast gfp_mask)
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
if (likely(size <= PAGE_SIZE)) {
|
||||
BUG_ON(!size);
|
||||
|
||||
+2
-1
@@ -58,7 +58,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
|
||||
* overflowing the unsigned long, but I don't think we would ever get
|
||||
* here if the volume was that big...
|
||||
*/
|
||||
index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
|
||||
index = (u64)ni->mft_no << vol->mft_record_size_bits >>
|
||||
PAGE_CACHE_SHIFT;
|
||||
ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
|
||||
|
||||
i_size = i_size_read(mft_vi);
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(posix_acl_permission);
|
||||
* Allocate a new ACL with the specified number of entries.
|
||||
*/
|
||||
struct posix_acl *
|
||||
posix_acl_alloc(int count, unsigned int __nocast flags)
|
||||
posix_acl_alloc(int count, gfp_t flags)
|
||||
{
|
||||
const size_t size = sizeof(struct posix_acl) +
|
||||
count * sizeof(struct posix_acl_entry);
|
||||
@@ -51,7 +51,7 @@ posix_acl_alloc(int count, unsigned int __nocast flags)
|
||||
* Clone an ACL.
|
||||
*/
|
||||
struct posix_acl *
|
||||
posix_acl_clone(const struct posix_acl *acl, unsigned int __nocast flags)
|
||||
posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
|
||||
{
|
||||
struct posix_acl *clone = NULL;
|
||||
|
||||
@@ -185,7 +185,7 @@ posix_acl_equiv_mode(const struct posix_acl *acl, mode_t *mode_p)
|
||||
* Create an ACL representing the file mode permission bits of an inode.
|
||||
*/
|
||||
struct posix_acl *
|
||||
posix_acl_from_mode(mode_t mode, unsigned int __nocast flags)
|
||||
posix_acl_from_mode(mode_t mode, gfp_t flags)
|
||||
{
|
||||
struct posix_acl *acl = posix_acl_alloc(3, flags);
|
||||
if (!acl)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user