diff options
author | David S. Miller <davem@davemloft.net> | 2013-07-03 17:50:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-03 17:55:13 -0400 |
commit | 0c1072ae0242fbdffd9a0bba36e7a7033d287f9c (patch) | |
tree | e0f4dbdbf5078d4a707911177e7bdc17a70bdce5 /fs | |
parent | c50cd357887acf9fd7af3a5d492911bd825555a2 (diff) | |
parent | 8bb495e3f02401ee6f76d1b1d77f3ac9f079e376 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/renesas/sh_eth.c
net/ipv4/gre.c
The GRE conflict is between a bug fix (kfree_skb --> kfree_skb_list)
and the splitting of the gre.c code into seperate files.
The FEC conflict was two sets of changes adding ethtool support code
in an "!CONFIG_M5272" CPP protected block.
Finally the sh_eth.c conflict was between one commit add bits set
in the .eesr_err_check mask whilst another commit removed the
.tx_error_check member and assignments.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exec.c | 16 | ||||
-rw-r--r-- | fs/fuse/file.c | 12 | ||||
-rw-r--r-- | fs/internal.h | 6 | ||||
-rw-r--r-- | fs/read_write.c | 24 | ||||
-rw-r--r-- | fs/splice.c | 32 | ||||
-rw-r--r-- | fs/ubifs/dir.c | 54 |
6 files changed, 97 insertions, 47 deletions
@@ -1135,13 +1135,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
1135 | set_dumpable(current->mm, suid_dumpable); | 1135 | set_dumpable(current->mm, suid_dumpable); |
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | /* | ||
1139 | * Flush performance counters when crossing a | ||
1140 | * security domain: | ||
1141 | */ | ||
1142 | if (!get_dumpable(current->mm)) | ||
1143 | perf_event_exit_task(current); | ||
1144 | |||
1145 | /* An exec changes our domain. We are no longer part of the thread | 1138 | /* An exec changes our domain. We are no longer part of the thread |
1146 | group */ | 1139 | group */ |
1147 | 1140 | ||
@@ -1205,6 +1198,15 @@ void install_exec_creds(struct linux_binprm *bprm) | |||
1205 | 1198 | ||
1206 | commit_creds(bprm->cred); | 1199 | commit_creds(bprm->cred); |
1207 | bprm->cred = NULL; | 1200 | bprm->cred = NULL; |
1201 | |||
1202 | /* | ||
1203 | * Disable monitoring for regular users | ||
1204 | * when executing setuid binaries. Must | ||
1205 | * wait until new credentials are committed | ||
1206 | * by commit_creds() above | ||
1207 | */ | ||
1208 | if (get_dumpable(current->mm) != SUID_DUMP_USER) | ||
1209 | perf_event_exit_task(current); | ||
1208 | /* | 1210 | /* |
1209 | * cred_guard_mutex must be held at least to this point to prevent | 1211 | * cred_guard_mutex must be held at least to this point to prevent |
1210 | * ptrace_attach() from altering our determination of the task's | 1212 | * ptrace_attach() from altering our determination of the task's |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e570081f9f76..35f281033142 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -2470,13 +2470,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2470 | .mode = mode | 2470 | .mode = mode |
2471 | }; | 2471 | }; |
2472 | int err; | 2472 | int err; |
2473 | bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || | ||
2474 | (mode & FALLOC_FL_PUNCH_HOLE); | ||
2473 | 2475 | ||
2474 | if (fc->no_fallocate) | 2476 | if (fc->no_fallocate) |
2475 | return -EOPNOTSUPP; | 2477 | return -EOPNOTSUPP; |
2476 | 2478 | ||
2477 | if (mode & FALLOC_FL_PUNCH_HOLE) { | 2479 | if (lock_inode) { |
2478 | mutex_lock(&inode->i_mutex); | 2480 | mutex_lock(&inode->i_mutex); |
2479 | fuse_set_nowrite(inode); | 2481 | if (mode & FALLOC_FL_PUNCH_HOLE) |
2482 | fuse_set_nowrite(inode); | ||
2480 | } | 2483 | } |
2481 | 2484 | ||
2482 | req = fuse_get_req_nopages(fc); | 2485 | req = fuse_get_req_nopages(fc); |
@@ -2511,8 +2514,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2511 | fuse_invalidate_attr(inode); | 2514 | fuse_invalidate_attr(inode); |
2512 | 2515 | ||
2513 | out: | 2516 | out: |
2514 | if (mode & FALLOC_FL_PUNCH_HOLE) { | 2517 | if (lock_inode) { |
2515 | fuse_release_nowrite(inode); | 2518 | if (mode & FALLOC_FL_PUNCH_HOLE) |
2519 | fuse_release_nowrite(inode); | ||
2516 | mutex_unlock(&inode->i_mutex); | 2520 | mutex_unlock(&inode->i_mutex); |
2517 | } | 2521 | } |
2518 | 2522 | ||
diff --git a/fs/internal.h b/fs/internal.h index eaa75f75b625..68121584ae37 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -132,6 +132,12 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); | |||
132 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); | 132 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * splice.c | ||
136 | */ | ||
137 | extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | ||
138 | loff_t *opos, size_t len, unsigned int flags); | ||
139 | |||
140 | /* | ||
135 | * pipe.c | 141 | * pipe.c |
136 | */ | 142 | */ |
137 | extern const struct file_operations pipefifo_fops; | 143 | extern const struct file_operations pipefifo_fops; |
diff --git a/fs/read_write.c b/fs/read_write.c index 03430008704e..2cefa417be34 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -1064,6 +1064,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1064 | struct fd in, out; | 1064 | struct fd in, out; |
1065 | struct inode *in_inode, *out_inode; | 1065 | struct inode *in_inode, *out_inode; |
1066 | loff_t pos; | 1066 | loff_t pos; |
1067 | loff_t out_pos; | ||
1067 | ssize_t retval; | 1068 | ssize_t retval; |
1068 | int fl; | 1069 | int fl; |
1069 | 1070 | ||
@@ -1077,12 +1078,14 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1077 | if (!(in.file->f_mode & FMODE_READ)) | 1078 | if (!(in.file->f_mode & FMODE_READ)) |
1078 | goto fput_in; | 1079 | goto fput_in; |
1079 | retval = -ESPIPE; | 1080 | retval = -ESPIPE; |
1080 | if (!ppos) | 1081 | if (!ppos) { |
1081 | ppos = &in.file->f_pos; | 1082 | pos = in.file->f_pos; |
1082 | else | 1083 | } else { |
1084 | pos = *ppos; | ||
1083 | if (!(in.file->f_mode & FMODE_PREAD)) | 1085 | if (!(in.file->f_mode & FMODE_PREAD)) |
1084 | goto fput_in; | 1086 | goto fput_in; |
1085 | retval = rw_verify_area(READ, in.file, ppos, count); | 1087 | } |
1088 | retval = rw_verify_area(READ, in.file, &pos, count); | ||
1086 | if (retval < 0) | 1089 | if (retval < 0) |
1087 | goto fput_in; | 1090 | goto fput_in; |
1088 | count = retval; | 1091 | count = retval; |
@@ -1099,7 +1102,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1099 | retval = -EINVAL; | 1102 | retval = -EINVAL; |
1100 | in_inode = file_inode(in.file); | 1103 | in_inode = file_inode(in.file); |
1101 | out_inode = file_inode(out.file); | 1104 | out_inode = file_inode(out.file); |
1102 | retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count); | 1105 | out_pos = out.file->f_pos; |
1106 | retval = rw_verify_area(WRITE, out.file, &out_pos, count); | ||
1103 | if (retval < 0) | 1107 | if (retval < 0) |
1104 | goto fput_out; | 1108 | goto fput_out; |
1105 | count = retval; | 1109 | count = retval; |
@@ -1107,7 +1111,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1107 | if (!max) | 1111 | if (!max) |
1108 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); | 1112 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); |
1109 | 1113 | ||
1110 | pos = *ppos; | ||
1111 | if (unlikely(pos + count > max)) { | 1114 | if (unlikely(pos + count > max)) { |
1112 | retval = -EOVERFLOW; | 1115 | retval = -EOVERFLOW; |
1113 | if (pos >= max) | 1116 | if (pos >= max) |
@@ -1126,18 +1129,23 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1126 | if (in.file->f_flags & O_NONBLOCK) | 1129 | if (in.file->f_flags & O_NONBLOCK) |
1127 | fl = SPLICE_F_NONBLOCK; | 1130 | fl = SPLICE_F_NONBLOCK; |
1128 | #endif | 1131 | #endif |
1129 | retval = do_splice_direct(in.file, ppos, out.file, count, fl); | 1132 | retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); |
1130 | 1133 | ||
1131 | if (retval > 0) { | 1134 | if (retval > 0) { |
1132 | add_rchar(current, retval); | 1135 | add_rchar(current, retval); |
1133 | add_wchar(current, retval); | 1136 | add_wchar(current, retval); |
1134 | fsnotify_access(in.file); | 1137 | fsnotify_access(in.file); |
1135 | fsnotify_modify(out.file); | 1138 | fsnotify_modify(out.file); |
1139 | out.file->f_pos = out_pos; | ||
1140 | if (ppos) | ||
1141 | *ppos = pos; | ||
1142 | else | ||
1143 | in.file->f_pos = pos; | ||
1136 | } | 1144 | } |
1137 | 1145 | ||
1138 | inc_syscr(current); | 1146 | inc_syscr(current); |
1139 | inc_syscw(current); | 1147 | inc_syscw(current); |
1140 | if (*ppos > max) | 1148 | if (pos > max) |
1141 | retval = -EOVERFLOW; | 1149 | retval = -EOVERFLOW; |
1142 | 1150 | ||
1143 | fput_out: | 1151 | fput_out: |
diff --git a/fs/splice.c b/fs/splice.c index e6b25598c8c4..d37431dd60a1 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -1274,7 +1274,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, | |||
1274 | { | 1274 | { |
1275 | struct file *file = sd->u.file; | 1275 | struct file *file = sd->u.file; |
1276 | 1276 | ||
1277 | return do_splice_from(pipe, file, &file->f_pos, sd->total_len, | 1277 | return do_splice_from(pipe, file, sd->opos, sd->total_len, |
1278 | sd->flags); | 1278 | sd->flags); |
1279 | } | 1279 | } |
1280 | 1280 | ||
@@ -1283,6 +1283,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, | |||
1283 | * @in: file to splice from | 1283 | * @in: file to splice from |
1284 | * @ppos: input file offset | 1284 | * @ppos: input file offset |
1285 | * @out: file to splice to | 1285 | * @out: file to splice to |
1286 | * @opos: output file offset | ||
1286 | * @len: number of bytes to splice | 1287 | * @len: number of bytes to splice |
1287 | * @flags: splice modifier flags | 1288 | * @flags: splice modifier flags |
1288 | * | 1289 | * |
@@ -1294,7 +1295,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, | |||
1294 | * | 1295 | * |
1295 | */ | 1296 | */ |
1296 | long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | 1297 | long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, |
1297 | size_t len, unsigned int flags) | 1298 | loff_t *opos, size_t len, unsigned int flags) |
1298 | { | 1299 | { |
1299 | struct splice_desc sd = { | 1300 | struct splice_desc sd = { |
1300 | .len = len, | 1301 | .len = len, |
@@ -1302,6 +1303,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
1302 | .flags = flags, | 1303 | .flags = flags, |
1303 | .pos = *ppos, | 1304 | .pos = *ppos, |
1304 | .u.file = out, | 1305 | .u.file = out, |
1306 | .opos = opos, | ||
1305 | }; | 1307 | }; |
1306 | long ret; | 1308 | long ret; |
1307 | 1309 | ||
@@ -1325,7 +1327,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1325 | { | 1327 | { |
1326 | struct pipe_inode_info *ipipe; | 1328 | struct pipe_inode_info *ipipe; |
1327 | struct pipe_inode_info *opipe; | 1329 | struct pipe_inode_info *opipe; |
1328 | loff_t offset, *off; | 1330 | loff_t offset; |
1329 | long ret; | 1331 | long ret; |
1330 | 1332 | ||
1331 | ipipe = get_pipe_info(in); | 1333 | ipipe = get_pipe_info(in); |
@@ -1356,13 +1358,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1356 | return -EINVAL; | 1358 | return -EINVAL; |
1357 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) | 1359 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) |
1358 | return -EFAULT; | 1360 | return -EFAULT; |
1359 | off = &offset; | 1361 | } else { |
1360 | } else | 1362 | offset = out->f_pos; |
1361 | off = &out->f_pos; | 1363 | } |
1362 | 1364 | ||
1363 | ret = do_splice_from(ipipe, out, off, len, flags); | 1365 | ret = do_splice_from(ipipe, out, &offset, len, flags); |
1364 | 1366 | ||
1365 | if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) | 1367 | if (!off_out) |
1368 | out->f_pos = offset; | ||
1369 | else if (copy_to_user(off_out, &offset, sizeof(loff_t))) | ||
1366 | ret = -EFAULT; | 1370 | ret = -EFAULT; |
1367 | 1371 | ||
1368 | return ret; | 1372 | return ret; |
@@ -1376,13 +1380,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1376 | return -EINVAL; | 1380 | return -EINVAL; |
1377 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) | 1381 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) |
1378 | return -EFAULT; | 1382 | return -EFAULT; |
1379 | off = &offset; | 1383 | } else { |
1380 | } else | 1384 | offset = in->f_pos; |
1381 | off = &in->f_pos; | 1385 | } |
1382 | 1386 | ||
1383 | ret = do_splice_to(in, off, opipe, len, flags); | 1387 | ret = do_splice_to(in, &offset, opipe, len, flags); |
1384 | 1388 | ||
1385 | if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) | 1389 | if (!off_in) |
1390 | in->f_pos = offset; | ||
1391 | else if (copy_to_user(off_in, &offset, sizeof(loff_t))) | ||
1386 | ret = -EFAULT; | 1392 | ret = -EFAULT; |
1387 | 1393 | ||
1388 | return ret; | 1394 | return ret; |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index de08c92f2e23..605af512aec2 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -349,31 +349,50 @@ static unsigned int vfs_dent_type(uint8_t type) | |||
349 | static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) | 349 | static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
350 | { | 350 | { |
351 | int err, over = 0; | 351 | int err, over = 0; |
352 | loff_t pos = file->f_pos; | ||
352 | struct qstr nm; | 353 | struct qstr nm; |
353 | union ubifs_key key; | 354 | union ubifs_key key; |
354 | struct ubifs_dent_node *dent; | 355 | struct ubifs_dent_node *dent; |
355 | struct inode *dir = file_inode(file); | 356 | struct inode *dir = file_inode(file); |
356 | struct ubifs_info *c = dir->i_sb->s_fs_info; | 357 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
357 | 358 | ||
358 | dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos); | 359 | dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos); |
359 | 360 | ||
360 | if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2) | 361 | if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2) |
361 | /* | 362 | /* |
362 | * The directory was seek'ed to a senseless position or there | 363 | * The directory was seek'ed to a senseless position or there |
363 | * are no more entries. | 364 | * are no more entries. |
364 | */ | 365 | */ |
365 | return 0; | 366 | return 0; |
366 | 367 | ||
368 | if (file->f_version == 0) { | ||
369 | /* | ||
370 | * The file was seek'ed, which means that @file->private_data | ||
371 | * is now invalid. This may also be just the first | ||
372 | * 'ubifs_readdir()' invocation, in which case | ||
373 | * @file->private_data is NULL, and the below code is | ||
374 | * basically a no-op. | ||
375 | */ | ||
376 | kfree(file->private_data); | ||
377 | file->private_data = NULL; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * 'generic_file_llseek()' unconditionally sets @file->f_version to | ||
382 | * zero, and we use this for detecting whether the file was seek'ed. | ||
383 | */ | ||
384 | file->f_version = 1; | ||
385 | |||
367 | /* File positions 0 and 1 correspond to "." and ".." */ | 386 | /* File positions 0 and 1 correspond to "." and ".." */ |
368 | if (file->f_pos == 0) { | 387 | if (pos == 0) { |
369 | ubifs_assert(!file->private_data); | 388 | ubifs_assert(!file->private_data); |
370 | over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); | 389 | over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); |
371 | if (over) | 390 | if (over) |
372 | return 0; | 391 | return 0; |
373 | file->f_pos = 1; | 392 | file->f_pos = pos = 1; |
374 | } | 393 | } |
375 | 394 | ||
376 | if (file->f_pos == 1) { | 395 | if (pos == 1) { |
377 | ubifs_assert(!file->private_data); | 396 | ubifs_assert(!file->private_data); |
378 | over = filldir(dirent, "..", 2, 1, | 397 | over = filldir(dirent, "..", 2, 1, |
379 | parent_ino(file->f_path.dentry), DT_DIR); | 398 | parent_ino(file->f_path.dentry), DT_DIR); |
@@ -389,7 +408,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
389 | goto out; | 408 | goto out; |
390 | } | 409 | } |
391 | 410 | ||
392 | file->f_pos = key_hash_flash(c, &dent->key); | 411 | file->f_pos = pos = key_hash_flash(c, &dent->key); |
393 | file->private_data = dent; | 412 | file->private_data = dent; |
394 | } | 413 | } |
395 | 414 | ||
@@ -397,17 +416,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
397 | if (!dent) { | 416 | if (!dent) { |
398 | /* | 417 | /* |
399 | * The directory was seek'ed to and is now readdir'ed. | 418 | * The directory was seek'ed to and is now readdir'ed. |
400 | * Find the entry corresponding to @file->f_pos or the | 419 | * Find the entry corresponding to @pos or the closest one. |
401 | * closest one. | ||
402 | */ | 420 | */ |
403 | dent_key_init_hash(c, &key, dir->i_ino, file->f_pos); | 421 | dent_key_init_hash(c, &key, dir->i_ino, pos); |
404 | nm.name = NULL; | 422 | nm.name = NULL; |
405 | dent = ubifs_tnc_next_ent(c, &key, &nm); | 423 | dent = ubifs_tnc_next_ent(c, &key, &nm); |
406 | if (IS_ERR(dent)) { | 424 | if (IS_ERR(dent)) { |
407 | err = PTR_ERR(dent); | 425 | err = PTR_ERR(dent); |
408 | goto out; | 426 | goto out; |
409 | } | 427 | } |
410 | file->f_pos = key_hash_flash(c, &dent->key); | 428 | file->f_pos = pos = key_hash_flash(c, &dent->key); |
411 | file->private_data = dent; | 429 | file->private_data = dent; |
412 | } | 430 | } |
413 | 431 | ||
@@ -419,7 +437,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
419 | ubifs_inode(dir)->creat_sqnum); | 437 | ubifs_inode(dir)->creat_sqnum); |
420 | 438 | ||
421 | nm.len = le16_to_cpu(dent->nlen); | 439 | nm.len = le16_to_cpu(dent->nlen); |
422 | over = filldir(dirent, dent->name, nm.len, file->f_pos, | 440 | over = filldir(dirent, dent->name, nm.len, pos, |
423 | le64_to_cpu(dent->inum), | 441 | le64_to_cpu(dent->inum), |
424 | vfs_dent_type(dent->type)); | 442 | vfs_dent_type(dent->type)); |
425 | if (over) | 443 | if (over) |
@@ -435,9 +453,17 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
435 | } | 453 | } |
436 | 454 | ||
437 | kfree(file->private_data); | 455 | kfree(file->private_data); |
438 | file->f_pos = key_hash_flash(c, &dent->key); | 456 | file->f_pos = pos = key_hash_flash(c, &dent->key); |
439 | file->private_data = dent; | 457 | file->private_data = dent; |
440 | cond_resched(); | 458 | cond_resched(); |
459 | |||
460 | if (file->f_version == 0) | ||
461 | /* | ||
462 | * The file was seek'ed meanwhile, lets return and start | ||
463 | * reading direntries from the new position on the next | ||
464 | * invocation. | ||
465 | */ | ||
466 | return 0; | ||
441 | } | 467 | } |
442 | 468 | ||
443 | out: | 469 | out: |
@@ -448,15 +474,13 @@ out: | |||
448 | 474 | ||
449 | kfree(file->private_data); | 475 | kfree(file->private_data); |
450 | file->private_data = NULL; | 476 | file->private_data = NULL; |
477 | /* 2 is a special value indicating that there are no more direntries */ | ||
451 | file->f_pos = 2; | 478 | file->f_pos = 2; |
452 | return 0; | 479 | return 0; |
453 | } | 480 | } |
454 | 481 | ||
455 | /* If a directory is seeked, we have to free saved readdir() state */ | ||
456 | static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) | 482 | static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) |
457 | { | 483 | { |
458 | kfree(file->private_data); | ||
459 | file->private_data = NULL; | ||
460 | return generic_file_llseek(file, offset, whence); | 484 | return generic_file_llseek(file, offset, whence); |
461 | } | 485 | } |
462 | 486 | ||